| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import "ios/chrome/browser/ui/ntp/new_tab_page_toolbar_controller.h" |
| |
| #include "base/logging.h" |
| #include "base/metrics/user_metrics.h" |
| #include "base/metrics/user_metrics_action.h" |
| #include "components/strings/grit/components_strings.h" |
| #include "components/toolbar/toolbar_model.h" |
| #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" |
| #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" |
| #include "ios/chrome/browser/ui/commands/ios_command_ids.h" |
| #import "ios/chrome/browser/ui/ntp/google_landing_data_source.h" |
| #import "ios/chrome/browser/ui/rtl_geometry.h" |
| #include "ios/chrome/browser/ui/toolbar/toolbar_resource_macros.h" |
| #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h" |
| #import "ios/chrome/browser/ui/uikit_ui_util.h" |
| #include "ui/base/l10n/l10n_util.h" |
| |
| #if !defined(__has_feature) || !__has_feature(objc_arc) |
| #error "This file requires ARC support." |
| #endif |
| |
| using base::UserMetricsAction; |
| |
| namespace { |
| |
| const CGFloat kButtonYOffset = 4.0; |
| const CGFloat kBackButtonLeading = 0; |
| const CGFloat kForwardButtonLeading = 48; |
| const CGFloat kOmniboxFocuserLeading = 96; |
| const CGSize kBackButtonSize = {48, 48}; |
| const CGSize kForwardButtonSize = {48, 48}; |
| const CGSize kOmniboxFocuserSize = {128, 48}; |
| |
| enum { |
| NTPToolbarButtonNameBack = NumberOfToolbarButtonNames, |
| NTPToolbarButtonNameForward, |
| NumberOfNTPToolbarButtonNames, |
| }; |
| |
| } // namespace |
| |
| @interface NewTabPageToolbarController () { |
| UIButton* _backButton; |
| UIButton* _forwardButton; |
| UIButton* _omniboxFocuser; |
| } |
| |
| // |YES| if the google landing toolbar can show the forward arrow. |
| @property(nonatomic, assign) BOOL canGoForward; |
| |
| // |YES| if the google landing toolbar can show the back arrow. |
| @property(nonatomic, assign) BOOL canGoBack; |
| |
| @end |
| |
| @implementation NewTabPageToolbarController |
| |
| @synthesize dispatcher = _dispatcher; |
| @synthesize canGoForward = _canGoForward; |
| @synthesize canGoBack = _canGoBack; |
| |
| - (instancetype)init { |
| self = [super initWithStyle:ToolbarControllerStyleLightMode]; |
| if (self) { |
| [self.backgroundView setHidden:YES]; |
| |
| CGFloat boundingWidth = self.view.bounds.size.width; |
| LayoutRect backButtonLayout = |
| LayoutRectMake(kBackButtonLeading, boundingWidth, kButtonYOffset, |
| kBackButtonSize.width, kBackButtonSize.height); |
| _backButton = |
| [[UIButton alloc] initWithFrame:LayoutRectGetRect(backButtonLayout)]; |
| [_backButton |
| setAutoresizingMask:UIViewAutoresizingFlexibleTrailingMargin() | |
| UIViewAutoresizingFlexibleBottomMargin]; |
| LayoutRect forwardButtonLayout = |
| LayoutRectMake(kForwardButtonLeading, boundingWidth, kButtonYOffset, |
| kForwardButtonSize.width, kForwardButtonSize.height); |
| _forwardButton = |
| [[UIButton alloc] initWithFrame:LayoutRectGetRect(forwardButtonLayout)]; |
| [_forwardButton |
| setAutoresizingMask:UIViewAutoresizingFlexibleTrailingMargin() | |
| UIViewAutoresizingFlexibleBottomMargin]; |
| LayoutRect omniboxFocuserLayout = |
| LayoutRectMake(kOmniboxFocuserLeading, boundingWidth, kButtonYOffset, |
| kOmniboxFocuserSize.width, kOmniboxFocuserSize.height); |
| _omniboxFocuser = [[UIButton alloc] |
| initWithFrame:LayoutRectGetRect(omniboxFocuserLayout)]; |
| [_omniboxFocuser |
| setAccessibilityLabel:l10n_util::GetNSString(IDS_ACCNAME_LOCATION)]; |
| |
| [_omniboxFocuser setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; |
| |
| [self.view addSubview:_backButton]; |
| [self.view addSubview:_forwardButton]; |
| [self.view addSubview:_omniboxFocuser]; |
| [_backButton setImageEdgeInsets:UIEdgeInsetsMakeDirected(0, 0, 0, -10)]; |
| [_forwardButton setImageEdgeInsets:UIEdgeInsetsMakeDirected(0, -7, 0, 0)]; |
| |
| // Set up the button images. |
| [self setUpButton:_backButton |
| withImageEnum:NTPToolbarButtonNameBack |
| forInitialState:UIControlStateDisabled |
| hasDisabledImage:YES |
| synchronously:NO]; |
| [self setUpButton:_forwardButton |
| withImageEnum:NTPToolbarButtonNameForward |
| forInitialState:UIControlStateDisabled |
| hasDisabledImage:YES |
| synchronously:NO]; |
| |
| UILongPressGestureRecognizer* backLongPress = |
| [[UILongPressGestureRecognizer alloc] |
| initWithTarget:self |
| action:@selector(handleLongPress:)]; |
| [_backButton addGestureRecognizer:backLongPress]; |
| UILongPressGestureRecognizer* forwardLongPress = |
| [[UILongPressGestureRecognizer alloc] |
| initWithTarget:self |
| action:@selector(handleLongPress:)]; |
| [_forwardButton addGestureRecognizer:forwardLongPress]; |
| [_backButton setTag:IDC_BACK]; |
| [_forwardButton setTag:IDC_FORWARD]; |
| |
| [_omniboxFocuser addTarget:self |
| action:@selector(focusOmnibox:) |
| forControlEvents:UIControlEventTouchUpInside]; |
| |
| SetA11yLabelAndUiAutomationName(_backButton, IDS_ACCNAME_BACK, @"Back"); |
| SetA11yLabelAndUiAutomationName(_forwardButton, IDS_ACCNAME_FORWARD, |
| @"Forward"); |
| } |
| return self; |
| } |
| |
| - (CGFloat)statusBarOffset { |
| return 0; |
| } |
| |
| - (BOOL)imageShouldFlipForRightToLeftLayoutDirection:(int)imageEnum { |
| DCHECK(imageEnum < NumberOfNTPToolbarButtonNames); |
| if (imageEnum < NumberOfToolbarButtonNames) |
| return [super imageShouldFlipForRightToLeftLayoutDirection:imageEnum]; |
| if (imageEnum == NTPToolbarButtonNameBack || |
| imageEnum == NTPToolbarButtonNameForward) { |
| return YES; |
| } |
| return NO; |
| } |
| |
| - (int)imageEnumForButton:(UIButton*)button { |
| if (button == _backButton) |
| return NTPToolbarButtonNameBack; |
| if (button == _forwardButton) |
| return NTPToolbarButtonNameForward; |
| return [super imageEnumForButton:button]; |
| } |
| |
| - (int)imageIdForImageEnum:(int)index |
| style:(ToolbarControllerStyle)style |
| forState:(ToolbarButtonUIState)state { |
| DCHECK(style < ToolbarControllerStyleMaxStyles); |
| DCHECK(state < NumberOfToolbarButtonUIStates); |
| |
| if (index >= NumberOfNTPToolbarButtonNames) |
| NOTREACHED(); |
| if (index < NumberOfToolbarButtonNames) |
| return [super imageIdForImageEnum:index style:style forState:state]; |
| |
| index -= NumberOfToolbarButtonNames; |
| |
| const int numberOfAddedNames = |
| NumberOfNTPToolbarButtonNames - NumberOfToolbarButtonNames; |
| // Name, style [light, dark], UIControlState [normal, pressed, disabled] |
| static int |
| buttonImageIds[numberOfAddedNames][2][NumberOfToolbarButtonUIStates] = { |
| TOOLBAR_IDR_THREE_STATE(BACK), TOOLBAR_IDR_THREE_STATE(FORWARD), |
| }; |
| return buttonImageIds[index][style][state]; |
| } |
| |
| - (IBAction)recordUserMetrics:(id)sender { |
| if (sender == _backButton) { |
| base::RecordAction(UserMetricsAction("MobileToolbarBack")); |
| } else if (sender == _forwardButton) { |
| base::RecordAction(UserMetricsAction("MobileToolbarForward")); |
| } else { |
| [super recordUserMetrics:sender]; |
| } |
| } |
| |
| - (void)handleLongPress:(UILongPressGestureRecognizer*)gesture { |
| if (gesture.state != UIGestureRecognizerStateBegan) |
| return; |
| |
| if (gesture.view == _backButton) { |
| GenericChromeCommand* command = |
| [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_BACK_HISTORY]; |
| [_backButton chromeExecuteCommand:command]; |
| } else if (gesture.view == _forwardButton) { |
| GenericChromeCommand* command = |
| [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_FORWARD_HISTORY]; |
| [_forwardButton chromeExecuteCommand:command]; |
| } |
| } |
| |
| - (void)hideViewsForNewTabPage:(BOOL)hide { |
| [super hideViewsForNewTabPage:hide]; |
| // Show the back/forward buttons if there is forward history. |
| BOOL forwardEnabled = self.canGoForward; |
| [_backButton setHidden:!forwardEnabled && hide]; |
| [_backButton setEnabled:self.canGoBack]; |
| [_forwardButton setHidden:!forwardEnabled && hide]; |
| } |
| |
| - (void)focusOmnibox:(id)sender { |
| [self.dispatcher focusFakebox]; |
| } |
| |
| - (IBAction)stackButtonTouchDown:(id)sender { |
| [self.dispatcher prepareToEnterTabSwitcher:self]; |
| } |
| |
| @end |