Chromium Code Reviews| Index: ios/chrome/browser/ui/toolbar/keyboard_accessory_view.mm |
| diff --git a/ios/chrome/browser/ui/toolbar/keyboard_accessory_view.mm b/ios/chrome/browser/ui/toolbar/keyboard_accessory_view.mm |
| index 232218927e1a5036bd54e900b017a7e28e261748..5f10058f8583f4c2547425545b5ebd316b5b4e97 100644 |
| --- a/ios/chrome/browser/ui/toolbar/keyboard_accessory_view.mm |
| +++ b/ios/chrome/browser/ui/toolbar/keyboard_accessory_view.mm |
| @@ -4,8 +4,13 @@ |
| #import "ios/chrome/browser/ui/toolbar/keyboard_accessory_view.h" |
| +#import <NotificationCenter/NotificationCenter.h> |
| + |
| #include "base/mac/foundation_util.h" |
| +#include "ios/chrome/browser/experimental_flags.h" |
| #include "ios/chrome/browser/ui/commands/ios_command_ids.h" |
| +#import "ios/chrome/browser/ui/fancy_ui/colored_button.h" |
| +#include "ios/chrome/browser/ui/rtl_geometry.h" |
| #include "ios/chrome/browser/ui/ui_util.h" |
| #import "ios/chrome/browser/ui/uikit_ui_util.h" |
| #include "ios/chrome/grit/ios_strings.h" |
| @@ -21,6 +26,10 @@ @interface KeyboardAccessoryView () |
| // Creates a button with the same appearance as a keyboard key. |
| - (UIView*)keyboardButtonWithTitle:(NSString*)title frame:(CGRect)frame; |
| +// Creates a button shortcut for |title|. |
| +- (UIView*)newShortcutButtonWithTitle:(NSString*)title; |
| +// Creates a button with an icon based on |iconName|. |
| +- (UIButton*)newIconButton:(NSString*)iconName; |
| // Called when a keyboard shortcut button is pressed. |
| - (void)keyboardButtonPressed:(NSString*)title; |
| @@ -36,13 +45,6 @@ - (instancetype)initWithButtons:(NSArray<NSString*>*)buttonTitles |
| delegate:(id<KeyboardAccessoryViewDelegate>)delegate { |
| const CGFloat kViewHeight = 70.0; |
| const CGFloat kViewHeightCompact = 43.0; |
| - const CGFloat kButtonInset = 5.0; |
| - const CGFloat kButtonSizeX = 61.0; |
| - const CGFloat kButtonSizeXCompact = 46.0; |
| - const CGFloat kButtonSizeY = 62.0; |
| - const CGFloat kButtonSizeYCompact = 35.0; |
| - const CGFloat kBetweenButtonSpacing = 15.0; |
| - const CGFloat kBetweenButtonSpacingCompact = 7.0; |
| const BOOL isCompact = IsCompact(); |
| CGFloat width = [[UIScreen mainScreen] bounds].size.width; |
| @@ -52,68 +54,166 @@ - (instancetype)initWithButtons:(NSArray<NSString*>*)buttonTitles |
| self = [super initWithFrame:frame inputViewStyle:UIInputViewStyleKeyboard]; |
| if (self) { |
| _delegate = delegate; |
| + if (experimental_flags::IsNewKeyboardAccessoryViewEnabled()) { |
|
gambard
2017/06/09 12:35:42
This is a >160 lines methods. Maybe we can split i
jif
2017/06/09 13:19:37
Done.
|
| + const CGFloat kButtonMinSizeX = 61.0; |
| + const CGFloat kButtonMinSizeXCompact = 32.0; |
| + const CGFloat kButtonSizeY = 62.0; |
| + const CGFloat kButtonSizeYCompact = 30.0; |
| + const CGFloat kBetweenButtonSpacing = 15.0; |
| + const CGFloat kBetweenButtonSpacingCompact = 6.0; |
| + const CGFloat kSeparatorAlpha = 0.1; |
| - // Center buttons in available space by placing them within a parent view |
| - // that auto-centers. |
| - CGFloat betweenButtonSpacing = |
| - isCompact ? kBetweenButtonSpacingCompact : kBetweenButtonSpacing; |
| - const CGFloat buttonWidth = isCompact ? kButtonSizeXCompact : kButtonSizeX; |
| - |
| - CGFloat totalWidth = (buttonTitles.count * buttonWidth) + |
| - ((buttonTitles.count - 1) * betweenButtonSpacing); |
| - CGFloat indent = floor((width - totalWidth) / 2.0); |
| - if (indent < kButtonInset) |
| - indent = kButtonInset; |
| - CGRect parentViewRect = CGRectMake(indent, 0.0, totalWidth, height); |
| - UIView* parentView = [[UIView alloc] initWithFrame:parentViewRect]; |
| - [parentView setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | |
| - UIViewAutoresizingFlexibleRightMargin]; |
| - [self addSubview:parentView]; |
| - |
| - // Create the shortcut buttons, starting at the left edge of |parentView|. |
| - CGRect currentFrame = |
| - CGRectMake(0.0, kButtonInset, buttonWidth, |
| - isCompact ? kButtonSizeYCompact : kButtonSizeY); |
| - |
| - for (NSString* title in buttonTitles) { |
| - UIView* button = [self keyboardButtonWithTitle:title frame:currentFrame]; |
| - [parentView addSubview:button]; |
| - currentFrame.origin.x = |
| - CGRectGetMaxX(currentFrame) + betweenButtonSpacing; |
| - } |
| + // Create stackview filled with the shortcut buttons |
| + UIStackView* stackView = [[UIStackView alloc] init]; |
| + [stackView setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| + stackView.spacing = |
| + isCompact ? kBetweenButtonSpacingCompact : kBetweenButtonSpacing; |
| + for (NSString* title in buttonTitles) { |
| + UIView* button = [self newShortcutButtonWithTitle:title]; |
| + [button setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| + CGFloat buttonMinWidth = |
| + isCompact ? kButtonMinSizeXCompact : kButtonMinSizeX; |
| + [button.widthAnchor |
| + constraintGreaterThanOrEqualToConstant:buttonMinWidth] |
| + .active = YES; |
| + CGFloat buttonHeight = isCompact ? kButtonSizeYCompact : kButtonSizeY; |
| + [button.heightAnchor constraintEqualToConstant:buttonHeight].active = |
| + YES; |
| + [stackView addArrangedSubview:button]; |
| + } |
| + [self addSubview:stackView]; |
| + |
| + // Create and add image for camera search. |
| + UIButton* cameraButton = |
| + [self newIconButton:@"qr_scanner_keyboard_accessory"]; |
| + [cameraButton |
| + addTarget:delegate |
| + action:@selector(keyboardAccessoryCameraSearchTouchUpInside) |
| + forControlEvents:UIControlEventTouchUpInside]; |
| + [self addSubview:cameraButton]; |
| + |
| + _voiceSearchButton = |
| + [self newIconButton:@"voice_icon_keyboard_accessory"]; |
| + [self addSubview:_voiceSearchButton]; |
| + [_voiceSearchButton |
| + addTarget:delegate |
| + action:@selector(keyboardAccessoryVoiceSearchTouchDown) |
| + forControlEvents:UIControlEventTouchDown]; |
| + [_voiceSearchButton |
| + addTarget:delegate |
| + action:@selector(keyboardAccessoryVoiceSearchTouchUpInside) |
| + forControlEvents:UIControlEventTouchUpInside]; |
| + |
| + // Create separator |
| + UIView* separator = [[UIView alloc] init]; |
| + [separator setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| + [separator |
| + setBackgroundColor:[UIColor colorWithWhite:0 alpha:kSeparatorAlpha]]; |
| + [separator.heightAnchor |
| + constraintEqualToConstant:1.0 / [[UIScreen mainScreen] scale]] |
| + .active = YES; |
| + [self addSubview:separator]; |
| + |
| + // Position all the views. |
| + NSDictionary* viewsDictionary = @{ |
| + @"cameraButton" : cameraButton, |
| + @"voiceSearch" : _voiceSearchButton, |
| + @"stackView" : stackView, |
| + @"separator" : separator, |
| + }; |
| + NSArray* constraints = @[ |
| + @"H:|-8-[cameraButton]-8-[voiceSearch]-(>=16)-[stackView]", |
| + @"H:|-0-[separator]-0-|", |
| + @"V:[separator]-0-|", |
| + ]; |
| + ApplyVisualConstraintsWithOptions(constraints, viewsDictionary, |
| + LayoutOptionForRTLSupport(), self); |
| + AddSameCenterYConstraint(self, cameraButton); |
| + AddSameCenterYConstraint(self, _voiceSearchButton); |
| + AddSameCenterYConstraint(self, stackView); |
| + |
| + NSLayoutConstraint* horizontallyCenterStackViewConstraint = |
| + [self.centerXAnchor constraintEqualToAnchor:stackView.centerXAnchor]; |
| + horizontallyCenterStackViewConstraint.priority = |
| + UILayoutPriorityDefaultHigh; |
| + horizontallyCenterStackViewConstraint.active = YES; |
| + } else { |
| + const CGFloat kButtonInset = 5.0; |
| + const CGFloat kButtonSizeX = 61.0; |
| + const CGFloat kButtonSizeXCompact = 46.0; |
| + const CGFloat kButtonSizeY = 62.0; |
| + const CGFloat kButtonSizeYCompact = 35.0; |
| + const CGFloat kBetweenButtonSpacing = 15.0; |
| + const CGFloat kBetweenButtonSpacingCompact = 7.0; |
| + |
| + // Center buttons in available space by placing them within a parent view |
| + // that auto-centers. |
| + CGFloat betweenButtonSpacing = |
| + isCompact ? kBetweenButtonSpacingCompact : kBetweenButtonSpacing; |
| + const CGFloat buttonWidth = |
| + isCompact ? kButtonSizeXCompact : kButtonSizeX; |
| + |
| + CGFloat totalWidth = (buttonTitles.count * buttonWidth) + |
| + ((buttonTitles.count - 1) * betweenButtonSpacing); |
| + CGFloat indent = floor((width - totalWidth) / 2.0); |
| + if (indent < kButtonInset) |
| + indent = kButtonInset; |
| + CGRect parentViewRect = CGRectMake(indent, 0.0, totalWidth, height); |
| + UIView* parentView = [[UIView alloc] initWithFrame:parentViewRect]; |
| + [parentView setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | |
| + UIViewAutoresizingFlexibleRightMargin]; |
| + [self addSubview:parentView]; |
| + |
| + // Create the shortcut buttons, starting at the left edge of |parentView|. |
| + CGRect currentFrame = |
| + CGRectMake(0.0, kButtonInset, buttonWidth, |
| + isCompact ? kButtonSizeYCompact : kButtonSizeY); |
| + |
| + for (NSString* title in buttonTitles) { |
| + UIView* button = |
| + [self keyboardButtonWithTitle:title frame:currentFrame]; |
| + [parentView addSubview:button]; |
| + currentFrame.origin.x = |
| + CGRectGetMaxX(currentFrame) + betweenButtonSpacing; |
| + } |
| + |
| + // Create the voice search button and add it over the text buttons. |
| + _voiceSearchButton = [UIButton buttonWithType:UIButtonTypeCustom]; |
| + [_voiceSearchButton setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; |
| + SetA11yLabelAndUiAutomationName( |
| + _voiceSearchButton, IDS_IOS_ACCNAME_VOICE_SEARCH, @"Voice Search"); |
| + UIImage* voiceRow = [UIImage imageNamed:@"custom_row_voice"]; |
| + UIImage* voiceRowPressed = |
| + [UIImage imageNamed:@"custom_row_voice_pressed"]; |
| + [_voiceSearchButton setBackgroundImage:voiceRow |
| + forState:UIControlStateNormal]; |
| + [_voiceSearchButton setBackgroundImage:voiceRowPressed |
| + forState:UIControlStateHighlighted]; |
| - // Create the voice search button and add it over the text buttons. |
| - _voiceSearchButton = [UIButton buttonWithType:UIButtonTypeCustom]; |
| - [_voiceSearchButton setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; |
| - SetA11yLabelAndUiAutomationName( |
| - _voiceSearchButton, IDS_IOS_ACCNAME_VOICE_SEARCH, @"Voice Search"); |
| - UIImage* voiceRow = [UIImage imageNamed:@"custom_row_voice"]; |
| - UIImage* voiceRowPressed = [UIImage imageNamed:@"custom_row_voice_pressed"]; |
| - [_voiceSearchButton setBackgroundImage:voiceRow |
| - forState:UIControlStateNormal]; |
| - [_voiceSearchButton setBackgroundImage:voiceRowPressed |
| - forState:UIControlStateHighlighted]; |
| - |
| - UIImage* voiceIcon = [UIImage imageNamed:@"voice_icon_keyboard_accessory"]; |
| - [_voiceSearchButton setAdjustsImageWhenHighlighted:NO]; |
| - [_voiceSearchButton setImage:voiceIcon forState:UIControlStateNormal]; |
| - [_voiceSearchButton setFrame:[self bounds]]; |
| - |
| - [_voiceSearchButton |
| - addTarget:delegate |
| - action:@selector(keyboardAccessoryVoiceSearchTouchDown) |
| - forControlEvents:UIControlEventTouchDown]; |
| - [_voiceSearchButton |
| - addTarget:delegate |
| - action:@selector(keyboardAccessoryVoiceSearchTouchUpInside) |
| - forControlEvents:UIControlEventTouchUpInside]; |
| - [self addSubview:_voiceSearchButton]; |
| + UIImage* voiceIcon = |
| + [UIImage imageNamed:@"voice_icon_keyboard_accessory"]; |
| + [_voiceSearchButton setAdjustsImageWhenHighlighted:NO]; |
| + [_voiceSearchButton setImage:voiceIcon forState:UIControlStateNormal]; |
| + [_voiceSearchButton setFrame:[self bounds]]; |
| + [_voiceSearchButton |
| + addTarget:delegate |
| + action:@selector(keyboardAccessoryVoiceSearchTouchDown) |
| + forControlEvents:UIControlEventTouchDown]; |
| + [_voiceSearchButton |
| + addTarget:delegate |
| + action:@selector(keyboardAccessoryVoiceSearchTouchUpInside) |
| + forControlEvents:UIControlEventTouchUpInside]; |
| + [self addSubview:_voiceSearchButton]; |
| + } |
| } |
| return self; |
| } |
| - (void)setMode:(KeyboardAccessoryViewMode)mode { |
| + if (experimental_flags::IsNewKeyboardAccessoryViewEnabled()) { |
| + return; |
| + } |
| _mode = mode; |
| switch (mode) { |
| case VOICE_SEARCH: |
| @@ -152,6 +252,66 @@ - (UIView*)keyboardButtonWithTitle:(NSString*)title frame:(CGRect)frame { |
| return button; |
| } |
| +- (UIView*)newShortcutButtonWithTitle:(NSString*)title { |
|
gambard
2017/06/09 12:35:42
Don't start method with new to avoid memory issue.
jif
2017/06/09 13:19:37
Good catch :-)
Done and done.
|
| + const CGFloat kCornerRadius = 4.0; |
| + const CGFloat kAlphaStateNormal = 0.1; |
| + const CGFloat kAlphaStateHighlighted = 0.2; |
| + const CGFloat kHorizontalEdgeInset = 8; |
| + const CGFloat kIpadButtonTitleFontSize = 20.0; |
| + const CGFloat kIphoneButtonTitleFontSize = 15.0; |
| + |
| + ColoredButton* button = [ColoredButton buttonWithType:UIButtonTypeCustom]; |
| + UIFont* font = nil; |
| + |
| + [button setTitle:title forState:UIControlStateNormal]; |
| + [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; |
| + |
| + [button setBackgroundColor:UIColorFromRGB(0, kAlphaStateNormal) |
| + forState:UIControlStateNormal]; |
| + [button setBackgroundColor:UIColorFromRGB(0, kAlphaStateHighlighted) |
| + forState:UIControlStateHighlighted]; |
| + |
| + button.layer.cornerRadius = kCornerRadius; |
| + button.contentEdgeInsets = |
| + UIEdgeInsetsMake(0, kHorizontalEdgeInset, 0, kHorizontalEdgeInset); |
| + button.clipsToBounds = YES; |
| + |
| + if (IsIPadIdiom()) { |
| + font = GetUIFont(FONT_HELVETICA, false, kIpadButtonTitleFontSize); |
| + } else { |
| + font = GetUIFont(FONT_HELVETICA, true, kIphoneButtonTitleFontSize); |
| + } |
| + |
| + [button.titleLabel setFont:font]; |
| + |
| + [button addTarget:self |
| + action:@selector(keyboardButtonPressed:) |
| + forControlEvents:UIControlEventTouchUpInside]; |
| + button.isAccessibilityElement = YES; |
| + [button setAccessibilityLabel:title]; |
| + return button; |
| +} |
| + |
| +- (UIButton*)newIconButton:(NSString*)iconName { |
| + const CGFloat kIconTintAlphaStateNormal = 0.45; |
| + const CGFloat kIconTintAlphaStateHighlighted = 0.6; |
| + |
| + UIColor* iconTintStateNormal = UIColorFromRGB(0, kIconTintAlphaStateNormal); |
| + UIColor* iconTintStateHighlighted = |
| + UIColorFromRGB(0, kIconTintAlphaStateHighlighted); |
| + |
| + ColoredButton* button = [ColoredButton buttonWithType:UIButtonTypeCustom]; |
| + |
| + [button setTintColor:iconTintStateNormal forState:UIControlStateNormal]; |
| + [button setTintColor:iconTintStateHighlighted |
| + forState:UIControlStateHighlighted]; |
| + [button setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| + UIImage* icon = [[UIImage imageNamed:iconName] |
| + imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; |
| + [button setImage:icon forState:UIControlStateNormal]; |
| + return button; |
| +} |
| + |
| - (BOOL)enableInputClicksWhenVisible { |
| return YES; |
| } |