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

Side by Side Diff: ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm

Issue 2914193002: [iOS] Factor out the KeyboardAccessoryView. (Closed)
Patch Set: Addressed comments and broke retain cycle. Created 3 years, 6 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 | « ios/chrome/browser/ui/toolbar/keyboard_accessory_view.mm ('k') | 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/toolbar/web_toolbar_controller.h" 5 #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h"
6 6
7 #import <CoreLocation/CoreLocation.h> 7 #import <CoreLocation/CoreLocation.h>
8 #include <QuartzCore/QuartzCore.h> 8 #include <QuartzCore/QuartzCore.h>
9 9
10 #include <stdint.h> 10 #include <stdint.h>
(...skipping 28 matching lines...) Expand all
39 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" 39 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h"
40 #include "ios/chrome/browser/ui/commands/ios_command_ids.h" 40 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
41 #import "ios/chrome/browser/ui/history/tab_history_popup_controller.h" 41 #import "ios/chrome/browser/ui/history/tab_history_popup_controller.h"
42 #import "ios/chrome/browser/ui/image_util.h" 42 #import "ios/chrome/browser/ui/image_util.h"
43 #import "ios/chrome/browser/ui/keyboard/hardware_keyboard_watcher.h" 43 #import "ios/chrome/browser/ui/keyboard/hardware_keyboard_watcher.h"
44 #include "ios/chrome/browser/ui/omnibox/location_bar_controller_impl.h" 44 #include "ios/chrome/browser/ui/omnibox/location_bar_controller_impl.h"
45 #include "ios/chrome/browser/ui/omnibox/omnibox_view_ios.h" 45 #include "ios/chrome/browser/ui/omnibox/omnibox_view_ios.h"
46 #import "ios/chrome/browser/ui/popup_menu/popup_menu_view.h" 46 #import "ios/chrome/browser/ui/popup_menu/popup_menu_view.h"
47 #import "ios/chrome/browser/ui/reversed_animation.h" 47 #import "ios/chrome/browser/ui/reversed_animation.h"
48 #include "ios/chrome/browser/ui/rtl_geometry.h" 48 #include "ios/chrome/browser/ui/rtl_geometry.h"
49 #import "ios/chrome/browser/ui/toolbar/keyboard_accessory_view.h"
49 #import "ios/chrome/browser/ui/toolbar/toolbar_controller+protected.h" 50 #import "ios/chrome/browser/ui/toolbar/toolbar_controller+protected.h"
50 #import "ios/chrome/browser/ui/toolbar/toolbar_controller.h" 51 #import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
51 #import "ios/chrome/browser/ui/toolbar/toolbar_model_ios.h" 52 #import "ios/chrome/browser/ui/toolbar/toolbar_model_ios.h"
52 #include "ios/chrome/browser/ui/toolbar/toolbar_resource_macros.h" 53 #include "ios/chrome/browser/ui/toolbar/toolbar_resource_macros.h"
53 #include "ios/chrome/browser/ui/ui_util.h" 54 #include "ios/chrome/browser/ui/ui_util.h"
54 #import "ios/chrome/browser/ui/uikit_ui_util.h" 55 #import "ios/chrome/browser/ui/uikit_ui_util.h"
55 #import "ios/chrome/browser/ui/url_loader.h" 56 #import "ios/chrome/browser/ui/url_loader.h"
56 #import "ios/chrome/browser/ui/voice/text_to_speech_player.h" 57 #import "ios/chrome/browser/ui/voice/text_to_speech_player.h"
57 #import "ios/chrome/browser/ui/voice/voice_search_notification_names.h" 58 #import "ios/chrome/browser/ui/voice/voice_search_notification_names.h"
58 #import "ios/chrome/common/material_timing.h" 59 #import "ios/chrome/common/material_timing.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 // displayed. 109 // displayed.
109 const CGFloat kBackButtonTrailingPadding = 7.0; 110 const CGFloat kBackButtonTrailingPadding = 7.0;
110 const CGFloat kForwardButtonTrailingPadding = -1.0; 111 const CGFloat kForwardButtonTrailingPadding = -1.0;
111 const CGFloat kReloadButtonTrailingPadding = 4.0; 112 const CGFloat kReloadButtonTrailingPadding = 4.0;
112 113
113 // Cancel button sizing. 114 // Cancel button sizing.
114 const CGFloat kCancelButtonBottomMargin = 4.0; 115 const CGFloat kCancelButtonBottomMargin = 4.0;
115 const CGFloat kCancelButtonTopMargin = 4.0; 116 const CGFloat kCancelButtonTopMargin = 4.0;
116 const CGFloat kCancelButtonLeadingMargin = 7.0; 117 const CGFloat kCancelButtonLeadingMargin = 7.0;
117 const CGFloat kCancelButtonWidth = 40.0; 118 const CGFloat kCancelButtonWidth = 40.0;
118 const CGFloat kIpadButtonTitleFontSize = 20.0;
119 const CGFloat kIphoneButtonTitleFontSize = 15.0;
120 119
121 // Additional offset to adjust the y coordinate of the determinate progress bar 120 // Additional offset to adjust the y coordinate of the determinate progress bar
122 // up by. 121 // up by.
123 const CGFloat kDeterminateProgressBarYOffset = 1.0; 122 const CGFloat kDeterminateProgressBarYOffset = 1.0;
124 const CGFloat kMaterialProgressBarHeight = 2.0; 123 const CGFloat kMaterialProgressBarHeight = 2.0;
125 const CGFloat kLoadCompleteHideProgressBarDelay = 0.5; 124 const CGFloat kLoadCompleteHideProgressBarDelay = 0.5;
126 // The default position animation is 10 pixels toward the trailing side, so 125 // The default position animation is 10 pixels toward the trailing side, so
127 // that's a negative leading offset. 126 // that's a negative leading offset.
128 const LayoutOffset kPositionAnimationLeadingOffset = -10.0; 127 const LayoutOffset kPositionAnimationLeadingOffset = -10.0;
129 128
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 214
216 CGRect RectShiftedDownAndResizedForStatusBar(CGRect rect) { 215 CGRect RectShiftedDownAndResizedForStatusBar(CGRect rect) {
217 if (IsIPadIdiom()) 216 if (IsIPadIdiom())
218 return rect; 217 return rect;
219 rect.size.height -= StatusBarHeight(); 218 rect.size.height -= StatusBarHeight();
220 return RectShiftedDownForStatusBar(rect); 219 return RectShiftedDownForStatusBar(rect);
221 } 220 }
222 221
223 } // namespace 222 } // namespace
224 223
225 // View for the accessory view above the keyboard. Subclassed to allow playing
226 // input clicks when pressed.
227 @interface KeyboardAccessoryView : UIInputView<UIInputViewAudioFeedback>
228 @end
229
230 @implementation KeyboardAccessoryView
231
232 - (BOOL)enableInputClicksWhenVisible {
233 return YES;
234 }
235
236 @end
237
238 // TODO(crbug.com/619982) Remove this block and add CAAnimationDelegate when we 224 // TODO(crbug.com/619982) Remove this block and add CAAnimationDelegate when we
239 // switch the main bots to Xcode 8. 225 // switch the main bots to Xcode 8.
240 #if defined(__IPHONE_10_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0) 226 #if defined(__IPHONE_10_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0)
241 @interface WebToolbarController ()<CAAnimationDelegate> 227 @interface WebToolbarController ()<CAAnimationDelegate,
228 KeyboardAccessoryViewDelegate>
242 @end 229 @end
243 #endif 230 #endif
244 231
245 @interface WebToolbarController ()<LocationBarDelegate, 232 @interface WebToolbarController ()<LocationBarDelegate,
246 OmniboxPopupPositioner, 233 OmniboxPopupPositioner,
247 ToolbarFrameDelegate> { 234 ToolbarFrameDelegate> {
248 // Top-level view for web content. 235 // Top-level view for web content.
249 UIView* _webToolbar; 236 UIView* _webToolbar;
250 UIButton* _backButton; 237 UIButton* _backButton;
251 UIButton* _forwardButton; 238 UIButton* _forwardButton;
252 UIButton* _reloadButton; 239 UIButton* _reloadButton;
253 UIButton* _stopButton; 240 UIButton* _stopButton;
254 UIButton* _starButton; 241 UIButton* _starButton;
255 UIButton* _voiceSearchButton; 242 UIButton* _voiceSearchButton;
256 OmniboxTextFieldIOS* _omniBox; 243 OmniboxTextFieldIOS* _omniBox;
257 UIButton* _cancelButton; 244 UIButton* _cancelButton;
258 UIView* _keyBoardAccessoryView; 245 KeyboardAccessoryView* _keyBoardAccessoryView;
259 UIButton* _keyboardVoiceSearchButton;
260 // Progress bar used to show what fraction of the page has loaded. 246 // Progress bar used to show what fraction of the page has loaded.
261 MDCProgressView* _determinateProgressView; 247 MDCProgressView* _determinateProgressView;
262 UIImageView* _omniboxBackground; 248 UIImageView* _omniboxBackground;
263 BOOL _prerenderAnimating; 249 BOOL _prerenderAnimating;
264 UIImageView* _incognitoIcon; 250 UIImageView* _incognitoIcon;
265 UIView* _clippingView; 251 UIView* _clippingView;
266 252
267 std::unique_ptr<LocationBarController> _locationBar; 253 std::unique_ptr<LocationBarController> _locationBar;
268 BOOL _initialLayoutComplete; 254 BOOL _initialLayoutComplete;
269 // If |YES|, toolbar is incognito. 255 // If |YES|, toolbar is incognito.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 // Received when a TTS player has received audio data. 323 // Received when a TTS player has received audio data.
338 - (void)audioReadyForPlayback:(NSNotification*)notification; 324 - (void)audioReadyForPlayback:(NSNotification*)notification;
339 // Updates the TTS button depending on whether or not TTS is currently playing. 325 // Updates the TTS button depending on whether or not TTS is currently playing.
340 - (void)updateIsTTSPlaying:(NSNotification*)notify; 326 - (void)updateIsTTSPlaying:(NSNotification*)notify;
341 // Moves VoiceOver to the button used to perform a voice search. 327 // Moves VoiceOver to the button used to perform a voice search.
342 - (void)moveVoiceOverToVoiceSearchButton; 328 - (void)moveVoiceOverToVoiceSearchButton;
343 // Fade in and out toolbar items as the frame moves off screen. 329 // Fade in and out toolbar items as the frame moves off screen.
344 - (void)updateToolbarAlphaForFrame:(CGRect)frame; 330 - (void)updateToolbarAlphaForFrame:(CGRect)frame;
345 // Navigate to |query| from omnibox. 331 // Navigate to |query| from omnibox.
346 - (void)loadURLForQuery:(NSString*)query; 332 - (void)loadURLForQuery:(NSString*)query;
347 - (UIView*)keyboardButtonWithTitle:(NSString*)title frame:(CGRect)frame;
348 // Lazily instantiate the keyboard accessory view. 333 // Lazily instantiate the keyboard accessory view.
349 - (UIView*)keyboardAccessoryView; 334 - (UIView*)keyboardAccessoryView;
350 - (void)preloadVoiceSearch:(id)sender; 335 - (void)preloadVoiceSearch:(id)sender;
351 // Calculates the CGRect to use for the omnibox's frame. Also sets the frames 336 // Calculates the CGRect to use for the omnibox's frame. Also sets the frames
352 // of some buttons and |_webToolbar|. 337 // of some buttons and |_webToolbar|.
353 - (CGRect)newOmniboxFrame; 338 - (CGRect)newOmniboxFrame;
354 - (void)animateMaterialOmnibox; 339 - (void)animateMaterialOmnibox;
355 - (void)fadeInOmniboxTrailingView; 340 - (void)fadeInOmniboxTrailingView;
356 - (void)fadeInOmniboxLeadingView; 341 - (void)fadeInOmniboxLeadingView;
357 - (void)fadeOutOmniboxTrailingView; 342 - (void)fadeOutOmniboxTrailingView;
358 - (void)fadeOutOmniboxLeadingView; 343 - (void)fadeOutOmniboxLeadingView;
359 - (void)fadeInIncognitoIcon; 344 - (void)fadeInIncognitoIcon;
360 - (void)fadeOutIncognitoIcon; 345 - (void)fadeOutIncognitoIcon;
361 // Fade in the visible navigation buttons. 346 // Fade in the visible navigation buttons.
362 - (void)fadeInNavigationControls; 347 - (void)fadeInNavigationControls;
363 // Fade out the visible navigation buttons. 348 // Fade out the visible navigation buttons.
364 - (void)fadeOutNavigationControls; 349 - (void)fadeOutNavigationControls;
365 // When the collapse animation is complete, hide the Material background and 350 // When the collapse animation is complete, hide the Material background and
366 // restore the omnibox's background image. 351 // restore the omnibox's background image.
367 - (void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag; 352 - (void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag;
368 - (void)updateSnapshotWithWidth:(CGFloat)width forced:(BOOL)force; 353 - (void)updateSnapshotWithWidth:(CGFloat)width forced:(BOOL)force;
369 // Insert 'com' without the period if cursor is directly after a period. 354 // Insert 'com' without the period if cursor is directly after a period.
370 - (NSString*)updateTextForDotCom:(NSString*)text; 355 - (NSString*)updateTextForDotCom:(NSString*)text;
371 // Handle the user pressing a key in the keyboard accessory view.
372 - (void)pressKey:(id)sender;
373 @end 356 @end
374 357
375 @implementation WebToolbarController 358 @implementation WebToolbarController
376 359
377 @synthesize delegate = _delegate; 360 @synthesize delegate = _delegate;
378 @synthesize urlLoader = _urlLoader; 361 @synthesize urlLoader = _urlLoader;
379 362
380 - (instancetype)initWithDelegate:(id<WebToolbarDelegate>)delegate 363 - (instancetype)initWithDelegate:(id<WebToolbarDelegate>)delegate
381 urlLoader:(id<UrlLoader>)urlLoader 364 urlLoader:(id<UrlLoader>)urlLoader
382 browserState:(ios::ChromeBrowserState*)browserState 365 browserState:(ios::ChromeBrowserState*)browserState
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 if (IsIPadIdiom()) { 868 if (IsIPadIdiom()) {
886 // Update toolbar accessory views. 869 // Update toolbar accessory views.
887 BOOL isCompactTabletView = IsCompactTablet(self.view); 870 BOOL isCompactTabletView = IsCompactTablet(self.view);
888 [_voiceSearchButton setHidden:isCompactTabletView]; 871 [_voiceSearchButton setHidden:isCompactTabletView];
889 [_starButton setHidden:isCompactTabletView]; 872 [_starButton setHidden:isCompactTabletView];
890 [_reloadButton setHidden:isCompactTabletView]; 873 [_reloadButton setHidden:isCompactTabletView];
891 [_stopButton setHidden:isCompactTabletView]; 874 [_stopButton setHidden:isCompactTabletView];
892 [self updateToolbarState]; 875 [self updateToolbarState];
893 876
894 // Update keyboard accessory views. 877 // Update keyboard accessory views.
895 BOOL hidden = [_keyboardVoiceSearchButton isHidden]; 878 auto mode = _keyBoardAccessoryView.mode;
896 _keyBoardAccessoryView = nil; 879 _keyBoardAccessoryView = nil;
897 [_omniBox setInputAccessoryView:[self keyboardAccessoryView]]; 880 [_omniBox setInputAccessoryView:[self keyboardAccessoryView]];
898 [_keyboardVoiceSearchButton setHidden:hidden]; 881 _keyBoardAccessoryView.mode = mode;
899 if ([_omniBox isFirstResponder]) { 882 if ([_omniBox isFirstResponder]) {
900 [_omniBox reloadInputViews]; 883 [_omniBox reloadInputViews];
901 } 884 }
902 885
903 // Re-layout toolbar and omnibox. 886 // Re-layout toolbar and omnibox.
904 [_webToolbar setFrame:[self specificControlsArea]]; 887 [_webToolbar setFrame:[self specificControlsArea]];
905 [self layoutOmnibox]; 888 [self layoutOmnibox];
906 } 889 }
907 } 890 }
908 891
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 if (sender == _backButton) { 944 if (sender == _backButton) {
962 base::RecordAction(UserMetricsAction("MobileToolbarBack")); 945 base::RecordAction(UserMetricsAction("MobileToolbarBack"));
963 } else if (sender == _forwardButton) { 946 } else if (sender == _forwardButton) {
964 base::RecordAction(UserMetricsAction("MobileToolbarForward")); 947 base::RecordAction(UserMetricsAction("MobileToolbarForward"));
965 } else if (sender == _reloadButton) { 948 } else if (sender == _reloadButton) {
966 base::RecordAction(UserMetricsAction("MobileToolbarReload")); 949 base::RecordAction(UserMetricsAction("MobileToolbarReload"));
967 } else if (sender == _stopButton) { 950 } else if (sender == _stopButton) {
968 base::RecordAction(UserMetricsAction("MobileToolbarStop")); 951 base::RecordAction(UserMetricsAction("MobileToolbarStop"));
969 } else if (sender == _voiceSearchButton) { 952 } else if (sender == _voiceSearchButton) {
970 base::RecordAction(UserMetricsAction("MobileToolbarVoiceSearch")); 953 base::RecordAction(UserMetricsAction("MobileToolbarVoiceSearch"));
971 } else if (sender == _keyboardVoiceSearchButton) {
972 base::RecordAction(UserMetricsAction("MobileCustomRowVoiceSearch"));
973 } else if (sender == _starButton) { 954 } else if (sender == _starButton) {
974 base::RecordAction(UserMetricsAction("MobileToolbarToggleBookmark")); 955 base::RecordAction(UserMetricsAction("MobileToolbarToggleBookmark"));
975 } else { 956 } else {
976 [super recordUserMetrics:sender]; 957 [super recordUserMetrics:sender];
977 } 958 }
978 } 959 }
979 960
980 - (IBAction)stackButtonTouchDown:(id)sender { 961 - (IBAction)stackButtonTouchDown:(id)sender {
981 [self.delegate prepareToEnterTabSwitcher:self]; 962 [self.delegate prepareToEnterTabSwitcher:self];
982 } 963 }
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 kLocationAuthorizationStatusCount); 1254 kLocationAuthorizationStatusCount);
1274 } 1255 }
1275 } 1256 }
1276 [self cancelOmniboxEdit]; 1257 [self cancelOmniboxEdit];
1277 } 1258 }
1278 1259
1279 - (void)locationBarHasBecomeFirstResponder { 1260 - (void)locationBarHasBecomeFirstResponder {
1280 [self.delegate locationBarDidBecomeFirstResponder:self]; 1261 [self.delegate locationBarDidBecomeFirstResponder:self];
1281 [self animateMaterialOmnibox]; 1262 [self animateMaterialOmnibox];
1282 1263
1283 [_keyboardVoiceSearchButton setHidden:NO]; 1264 _keyBoardAccessoryView.mode = VOICE_SEARCH;
1284 1265
1285 // Record the appropriate user action for focusing the omnibox. 1266 // Record the appropriate user action for focusing the omnibox.
1286 web::WebState* webState = [self.delegate currentWebState]; 1267 web::WebState* webState = [self.delegate currentWebState];
1287 if (webState) { 1268 if (webState) {
1288 if (webState->GetVisibleURL() == GURL(kChromeUINewTabURL)) { 1269 if (webState->GetVisibleURL() == GURL(kChromeUINewTabURL)) {
1289 OmniboxEditModel* model = _locationBar->GetLocationEntry()->model(); 1270 OmniboxEditModel* model = _locationBar->GetLocationEntry()->model();
1290 if (model->is_caret_visible()) { 1271 if (model->is_caret_visible()) {
1291 base::RecordAction( 1272 base::RecordAction(
1292 base::UserMetricsAction("MobileFocusedOmniboxOnNtp")); 1273 base::UserMetricsAction("MobileFocusedOmniboxOnNtp"));
1293 } else { 1274 } else {
(...skipping 17 matching lines...) Expand all
1311 } 1292 }
1312 1293
1313 - (void)locationBarChanged { 1294 - (void)locationBarChanged {
1314 // Hide the voice search button once the user starts editing the omnibox but 1295 // Hide the voice search button once the user starts editing the omnibox but
1315 // show it if the omnibox is empty. 1296 // show it if the omnibox is empty.
1316 bool isEditingOrEmpty = _locationBar->GetLocationEntry()->IsEditingOrEmpty(); 1297 bool isEditingOrEmpty = _locationBar->GetLocationEntry()->IsEditingOrEmpty();
1317 BOOL editingAndNotEmpty = isEditingOrEmpty && _omniBox.text.length != 0; 1298 BOOL editingAndNotEmpty = isEditingOrEmpty && _omniBox.text.length != 0;
1318 // If the voice search button is visible but about to be hidden (i.e. 1299 // If the voice search button is visible but about to be hidden (i.e.
1319 // the omnibox is no longer empty) then this is the first omnibox text so 1300 // the omnibox is no longer empty) then this is the first omnibox text so
1320 // record a user action. 1301 // record a user action.
1321 if (![_keyboardVoiceSearchButton isHidden] && editingAndNotEmpty) { 1302 if (_keyBoardAccessoryView.mode == VOICE_SEARCH && editingAndNotEmpty) {
1322 base::RecordAction(UserMetricsAction("MobileFirstTextInOmnibox")); 1303 base::RecordAction(UserMetricsAction("MobileFirstTextInOmnibox"));
1323 } 1304 }
1324 [_keyboardVoiceSearchButton setHidden:editingAndNotEmpty]; 1305 if (editingAndNotEmpty) {
1306 _keyBoardAccessoryView.mode = KEY_SHORTCUTS;
1307 } else {
1308 _keyBoardAccessoryView.mode = VOICE_SEARCH;
1309 }
1325 } 1310 }
1326 1311
1327 - (web::WebState*)getWebState { 1312 - (web::WebState*)getWebState {
1328 return [self.delegate currentWebState]; 1313 return [self.delegate currentWebState];
1329 } 1314 }
1330 1315
1331 - (ToolbarModel*)toolbarModel { 1316 - (ToolbarModel*)toolbarModel {
1332 ToolbarModelIOS* toolbarModelIOS = [self.delegate toolbarModelIOS]; 1317 ToolbarModelIOS* toolbarModelIOS = [self.delegate toolbarModelIOS];
1333 return toolbarModelIOS ? toolbarModelIOS->GetToolbarModel() : nullptr; 1318 return toolbarModelIOS ? toolbarModelIOS->GetToolbarModel() : nullptr;
1334 } 1319 }
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 [self focusOmnibox]; 1451 [self focusOmnibox];
1467 [_omniBox insertTextWhileEditing:result]; 1452 [_omniBox insertTextWhileEditing:result];
1468 // Notify the accessibility system to start reading the new contents of the 1453 // Notify the accessibility system to start reading the new contents of the
1469 // Omnibox. 1454 // Omnibox.
1470 UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, 1455 UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification,
1471 _omniBox); 1456 _omniBox);
1472 } 1457 }
1473 } 1458 }
1474 1459
1475 #pragma mark - 1460 #pragma mark -
1461 #pragma mark KeyboardAccessoryViewDelegate
1462
1463 - (void)keyboardAccessoryVoiceSearchTouchDown {
1464 if (ios::GetChromeBrowserProvider()
1465 ->GetVoiceSearchProvider()
1466 ->IsVoiceSearchEnabled()) {
1467 [self preloadVoiceSearch:_keyBoardAccessoryView];
1468 }
1469 }
1470
1471 - (void)keyboardAccessoryVoiceSearchTouchUpInside {
1472 if (ios::GetChromeBrowserProvider()
1473 ->GetVoiceSearchProvider()
1474 ->IsVoiceSearchEnabled()) {
1475 base::RecordAction(UserMetricsAction("MobileCustomRowVoiceSearch"));
1476 GenericChromeCommand* command =
1477 [[GenericChromeCommand alloc] initWithTag:IDC_VOICE_SEARCH];
1478 [_keyBoardAccessoryView chromeExecuteCommand:command];
1479 } else {
1480 _keyBoardAccessoryView.mode = KEY_SHORTCUTS;
1481 }
1482 }
1483
1484 - (void)keyPressed:(NSString*)title {
1485 NSString* text = [self updateTextForDotCom:title];
1486 [_omniBox insertTextWhileEditing:text];
1487 }
1488
1489 #pragma mark -
1476 #pragma mark Private methods. 1490 #pragma mark Private methods.
1477 1491
1478 - (UIButton*)cancelButton { 1492 - (UIButton*)cancelButton {
1479 if (_cancelButton) 1493 if (_cancelButton)
1480 return _cancelButton; 1494 return _cancelButton;
1481 _cancelButton = [UIButton buttonWithType:UIButtonTypeCustom]; 1495 _cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
1482 NSString* collapseName = _incognito ? @"collapse_incognito" : @"collapse"; 1496 NSString* collapseName = _incognito ? @"collapse_incognito" : @"collapse";
1483 [_cancelButton setImage:[UIImage imageNamed:collapseName] 1497 [_cancelButton setImage:[UIImage imageNamed:collapseName]
1484 forState:UIControlStateNormal]; 1498 forState:UIControlStateNormal];
1485 NSString* collapsePressedName = 1499 NSString* collapsePressedName =
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1820 // URL. 1834 // URL.
1821 ui::PageTransition transition = ui::PageTransitionFromInt( 1835 ui::PageTransition transition = ui::PageTransitionFromInt(
1822 ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR); 1836 ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
1823 [self.urlLoader loadURL:GURL(searchURL) 1837 [self.urlLoader loadURL:GURL(searchURL)
1824 referrer:web::Referrer() 1838 referrer:web::Referrer()
1825 transition:transition 1839 transition:transition
1826 rendererInitiated:NO]; 1840 rendererInitiated:NO];
1827 } 1841 }
1828 } 1842 }
1829 1843
1830 - (UIView*)keyboardButtonWithTitle:(NSString*)title frame:(CGRect)frame { 1844 - (UIView*)keyboardAccessoryView {
1831 UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom]; 1845 if (!_keyBoardAccessoryView) {
1832 UIFont* font = nil; 1846 NSArray<NSString*>* buttonTitles =
1833 UIImage* backgroundImage = nil; 1847 [NSArray arrayWithObjects:@":", @".", @"-", @"/", kDotComTLD, nil];
1834 if (IsIPadIdiom()) { 1848 _keyBoardAccessoryView =
1835 font = GetUIFont(FONT_HELVETICA, false, kIpadButtonTitleFontSize); 1849 [[KeyboardAccessoryView alloc] initWithButtons:buttonTitles
1836 } else { 1850 delegate:self];
1837 font = GetUIFont(FONT_HELVETICA, true, kIphoneButtonTitleFontSize); 1851 [_keyBoardAccessoryView
1852 setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
1853 _hardwareKeyboardWatcher = [[HardwareKeyboardWatcher alloc]
1854 initWithAccessoryView:_keyBoardAccessoryView];
1838 } 1855 }
1839 // TODO(leng): Consider moving these images to pak files as well.
1840 backgroundImage = [UIImage imageNamed:@"keyboard_button"];
1841
1842 button.frame = frame;
1843 [button setTitle:title forState:UIControlStateNormal];
1844 [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
1845 [button.titleLabel setFont:font];
1846 [button setBackgroundImage:backgroundImage forState:UIControlStateNormal];
1847 [button addTarget:self
1848 action:@selector(pressKey:)
1849 forControlEvents:UIControlEventTouchUpInside];
1850 button.isAccessibilityElement = YES;
1851 [button setAccessibilityLabel:title];
1852
1853 return button;
1854 }
1855
1856 - (UIView*)keyboardAccessoryView {
1857 const CGFloat kViewHeightTablet = 70.0;
1858 const CGFloat kViewHeightPhone = 43.0;
1859 const CGFloat kButtonInset = 5.0;
1860 const CGFloat kButtonSizeXTablet = 61.0;
1861 const CGFloat kButtonSizeXPhone = 46.0;
1862 const CGFloat kButtonSizeYTablet = 62.0;
1863 const CGFloat kButtonSizeYPhone = 35.0;
1864 const CGFloat kBetweenButtonSpacing = 15.0;
1865 const CGFloat kBetweenButtonSpacingPhone = 7.0;
1866
1867 if (_keyBoardAccessoryView)
1868 return _keyBoardAccessoryView;
1869
1870 const BOOL isTablet = IsIPadIdiom() && !IsCompactTablet(self.view);
1871
1872 // TODO(pinkerton): purge this view when low memory.
1873 CGFloat width = [[UIScreen mainScreen] bounds].size.width;
1874 CGFloat height = isTablet ? kViewHeightTablet : kViewHeightPhone;
1875 CGRect frame = CGRectMake(0.0, 0.0, width, height);
1876
1877 _keyBoardAccessoryView =
1878 [[KeyboardAccessoryView alloc] initWithFrame:frame
1879 inputViewStyle:UIInputViewStyleKeyboard];
1880 [_keyBoardAccessoryView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
1881
1882 NSArray* buttonTitles =
1883 [NSArray arrayWithObjects:@":", @".", @"-", @"/", kDotComTLD, nil];
1884
1885 // Center buttons in available space by placing them within a parent view
1886 // that auto-centers.
1887 CGFloat betweenButtonSpacing =
1888 isTablet ? kBetweenButtonSpacing : kBetweenButtonSpacingPhone;
1889 const CGFloat buttonWidth = isTablet ? kButtonSizeXTablet : kButtonSizeXPhone;
1890
1891 CGFloat totalWidth = (buttonTitles.count * buttonWidth) +
1892 ((buttonTitles.count - 1) * betweenButtonSpacing);
1893 CGFloat indent = floor((width - totalWidth) / 2.0);
1894 if (indent < kButtonInset)
1895 indent = kButtonInset;
1896 CGRect parentViewRect = CGRectMake(indent, 0.0, totalWidth, height);
1897 UIView* parentView = [[UIView alloc] initWithFrame:parentViewRect];
1898 [parentView setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin |
1899 UIViewAutoresizingFlexibleRightMargin];
1900 [_keyBoardAccessoryView addSubview:parentView];
1901
1902 // Create the buttons, starting at the left edge of |parentView|.
1903 CGRect currentFrame =
1904 CGRectMake(0.0, kButtonInset, buttonWidth,
1905 isTablet ? kButtonSizeYTablet : kButtonSizeYPhone);
1906
1907 for (NSString* title in buttonTitles) {
1908 UIView* button = [self keyboardButtonWithTitle:title frame:currentFrame];
1909 [parentView addSubview:button];
1910 currentFrame.origin.x = CGRectGetMaxX(currentFrame) + betweenButtonSpacing;
1911 }
1912
1913 // Create the voice search button and add it to _keyBoardAccessoryView over
1914 // the text buttons.
1915 _keyboardVoiceSearchButton = [UIButton buttonWithType:UIButtonTypeCustom];
1916 [_keyboardVoiceSearchButton
1917 setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
1918 [_keyboardVoiceSearchButton setTag:IDC_VOICE_SEARCH];
1919 SetA11yLabelAndUiAutomationName(_keyboardVoiceSearchButton,
1920 IDS_IOS_ACCNAME_VOICE_SEARCH,
1921 @"Voice Search");
1922 // TODO(leng): Consider moving these icons into a pak file.
1923 UIImage* voiceRow = [UIImage imageNamed:@"custom_row_voice"];
1924 UIImage* voiceRowPressed = [UIImage imageNamed:@"custom_row_voice_pressed"];
1925 [_keyboardVoiceSearchButton setBackgroundImage:voiceRow
1926 forState:UIControlStateNormal];
1927 [_keyboardVoiceSearchButton setBackgroundImage:voiceRowPressed
1928 forState:UIControlStateHighlighted];
1929
1930 UIImage* voiceIcon = [UIImage imageNamed:@"voice_icon_keyboard_accessory"];
1931 [_keyboardVoiceSearchButton setAdjustsImageWhenHighlighted:NO];
1932 [_keyboardVoiceSearchButton setImage:voiceIcon forState:UIControlStateNormal];
1933 [_keyboardVoiceSearchButton setFrame:[_keyBoardAccessoryView bounds]];
1934
1935 // Only add the voice search actions if voice search is enabled.
1936 if (ios::GetChromeBrowserProvider()
1937 ->GetVoiceSearchProvider()
1938 ->IsVoiceSearchEnabled()) {
1939 [_keyboardVoiceSearchButton addTarget:self
1940 action:@selector(recordUserMetrics:)
1941 forControlEvents:UIControlEventTouchUpInside];
1942 [_keyboardVoiceSearchButton addTarget:_keyboardVoiceSearchButton
1943 action:@selector(chromeExecuteCommand:)
1944 forControlEvents:UIControlEventTouchUpInside];
1945 [_keyboardVoiceSearchButton addTarget:self
1946 action:@selector(preloadVoiceSearch:)
1947 forControlEvents:UIControlEventTouchDown];
1948 } else {
1949 [_keyboardVoiceSearchButton addTarget:self
1950 action:@selector(ignoreVoiceSearch:)
1951 forControlEvents:UIControlEventTouchUpInside];
1952 }
1953
1954 [_keyBoardAccessoryView addSubview:_keyboardVoiceSearchButton];
1955
1956 // Reset the external keyboard watcher.
1957 _hardwareKeyboardWatcher = [[HardwareKeyboardWatcher alloc]
1958 initWithAccessoryView:_keyBoardAccessoryView];
1959
1960 return _keyBoardAccessoryView; 1856 return _keyBoardAccessoryView;
1961 } 1857 }
1962 1858
1963 - (void)preloadVoiceSearch:(id)sender { 1859 - (void)preloadVoiceSearch:(id)sender {
1964 DCHECK(ios::GetChromeBrowserProvider() 1860 DCHECK(ios::GetChromeBrowserProvider()
1965 ->GetVoiceSearchProvider() 1861 ->GetVoiceSearchProvider()
1966 ->IsVoiceSearchEnabled()); 1862 ->IsVoiceSearchEnabled());
1967 [sender removeTarget:self
1968 action:@selector(preloadVoiceSearch:)
1969 forControlEvents:UIControlEventTouchDown];
1970
1971 // Use a GenericChromeCommand because |sender| already has a tag set for a 1863 // Use a GenericChromeCommand because |sender| already has a tag set for a
1972 // different command. 1864 // different command.
1973 GenericChromeCommand* command = 1865 GenericChromeCommand* command =
1974 [[GenericChromeCommand alloc] initWithTag:IDC_PRELOAD_VOICE_SEARCH]; 1866 [[GenericChromeCommand alloc] initWithTag:IDC_PRELOAD_VOICE_SEARCH];
1975 [sender chromeExecuteCommand:command]; 1867 [sender chromeExecuteCommand:command];
1976 } 1868 }
1977 1869
1978 // Called when the keyboard voice search button is tapped with voice search
1979 // disabled. Hides the voice search button but takes no other action.
1980 - (void)ignoreVoiceSearch:(id)sender {
1981 [_keyboardVoiceSearchButton setHidden:YES];
1982 }
1983
1984 - (CGFloat)omniboxLeading { 1870 - (CGFloat)omniboxLeading {
1985 // Compute what the leading (x-origin) position for the omniboox should be 1871 // Compute what the leading (x-origin) position for the omniboox should be
1986 // based on what other controls are active. 1872 // based on what other controls are active.
1987 InterfaceIdiom idiom = IsIPadIdiom() ? IPAD_IDIOM : IPHONE_IDIOM; 1873 InterfaceIdiom idiom = IsIPadIdiom() ? IPAD_IDIOM : IPHONE_IDIOM;
1988 1874
1989 CGFloat trailingPadding = 0.0; 1875 CGFloat trailingPadding = 0.0;
1990 1876
1991 LayoutRect leadingControlLayout = LayoutRectForRectInBoundingRect( 1877 LayoutRect leadingControlLayout = LayoutRectForRectInBoundingRect(
1992 [_backButton frame], [_webToolbar bounds]); 1878 [_backButton frame], [_webToolbar bounds]);
1993 LayoutRect forwardButtonLayout = 1879 LayoutRect forwardButtonLayout =
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
2523 if ([text isEqualToString:kDotComTLD]) { 2409 if ([text isEqualToString:kDotComTLD]) {
2524 UITextRange* textRange = [_omniBox selectedTextRange]; 2410 UITextRange* textRange = [_omniBox selectedTextRange];
2525 NSInteger pos = [_omniBox offsetFromPosition:[_omniBox beginningOfDocument] 2411 NSInteger pos = [_omniBox offsetFromPosition:[_omniBox beginningOfDocument]
2526 toPosition:textRange.start]; 2412 toPosition:textRange.start];
2527 if (pos > 0 && [[_omniBox text] characterAtIndex:pos - 1] == '.') 2413 if (pos > 0 && [[_omniBox text] characterAtIndex:pos - 1] == '.')
2528 return [kDotComTLD substringFromIndex:1]; 2414 return [kDotComTLD substringFromIndex:1];
2529 } 2415 }
2530 return text; 2416 return text;
2531 } 2417 }
2532 2418
2533 - (void)pressKey:(id)sender {
2534 DCHECK([sender isKindOfClass:[UIButton class]]);
2535 [[UIDevice currentDevice] playInputClick];
2536 NSString* text = [self updateTextForDotCom:[sender currentTitle]];
2537 [_omniBox insertTextWhileEditing:text];
2538 }
2539
2540 @end 2419 @end
2541 2420
2542 @implementation WebToolbarController (Testing) 2421 @implementation WebToolbarController (Testing)
2543 2422
2544 - (BOOL)isForwardButtonEnabled { 2423 - (BOOL)isForwardButtonEnabled {
2545 return [_forwardButton isEnabled]; 2424 return [_forwardButton isEnabled];
2546 } 2425 }
2547 2426
2548 - (BOOL)isBackButtonEnabled { 2427 - (BOOL)isBackButtonEnabled {
2549 return [_backButton isEnabled]; 2428 return [_backButton isEnabled];
(...skipping 21 matching lines...) Expand all
2571 2450
2572 - (BOOL)isPrerenderAnimationRunning { 2451 - (BOOL)isPrerenderAnimationRunning {
2573 return _prerenderAnimating; 2452 return _prerenderAnimating;
2574 } 2453 }
2575 2454
2576 - (OmniboxTextFieldIOS*)omnibox { 2455 - (OmniboxTextFieldIOS*)omnibox {
2577 return _omniBox; 2456 return _omniBox;
2578 } 2457 }
2579 2458
2580 @end 2459 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/ui/toolbar/keyboard_accessory_view.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698