From b7a60b6c46e6a3c703a714d64b1786ad130c76c8 Mon Sep 17 00:00:00 2001 From: jyquinn Date: Tue, 5 Jul 2016 07:30:08 -0700 Subject: [PATCH] SelectorCoordinator for presenting a picker view from an infobar Add coordinator for presenting a picker view from an infobar, as needed in update passwords where there are multiple accounts, or in the translate infobar for language selection. Starting the coordinator animates the picker view in from the bottom edge of the baseViewController's view, and stopping animates it out. BUG=622244 Review-Url: https://codereview.chromium.org/2105253004 Cr-Commit-Position: refs/heads/master@{#403780} --- ios/chrome/BUILD.gn | 2 + ios/chrome/browser/BUILD.gn | 5 + .../ui/elements/selector_coordinator.h | 33 ++++ .../ui/elements/selector_coordinator.mm | 70 ++++++++ .../elements/selector_coordinator_unittest.mm | 70 ++++++++ .../selector_picker_view_controller.h | 30 ++++ .../selector_picker_view_controller.mm | 157 ++++++++++++++++++ ...elector_picker_view_controller_unittest.mm | 112 +++++++++++++ .../selector_view_controller_delegate.h | 16 ++ ios/chrome/ios_chrome.gyp | 15 +- ios/chrome/ios_chrome_tests.gyp | 2 + 11 files changed, 507 insertions(+), 5 deletions(-) create mode 100644 ios/chrome/browser/ui/elements/selector_coordinator.h create mode 100644 ios/chrome/browser/ui/elements/selector_coordinator.mm create mode 100644 ios/chrome/browser/ui/elements/selector_coordinator_unittest.mm create mode 100644 ios/chrome/browser/ui/elements/selector_picker_view_controller.h create mode 100644 ios/chrome/browser/ui/elements/selector_picker_view_controller.mm create mode 100644 ios/chrome/browser/ui/elements/selector_picker_view_controller_unittest.mm create mode 100644 ios/chrome/browser/ui/elements/selector_view_controller_delegate.h diff --git a/ios/chrome/BUILD.gn b/ios/chrome/BUILD.gn index 892f04fb9831f3..0d2daa33ffad5a 100644 --- a/ios/chrome/BUILD.gn +++ b/ios/chrome/BUILD.gn @@ -55,6 +55,8 @@ test("ios_chrome_unittests") { "browser/translate/translate_service_ios_unittest.cc", "browser/ui/commands/set_up_for_testing_command_unittest.mm", "browser/ui/context_menu/context_menu_coordinator_unittest.mm", + "browser/ui/elements/selector_coordinator_unittest.mm", + "browser/ui/elements/selector_picker_view_controller_unittest.mm", "browser/ui/keyboard/UIKeyCommand+ChromeTest.mm", "browser/ui/keyboard/hardware_keyboard_watcher_unittest.mm", "browser/ui/native_content_controller_unittest.mm", diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn index c121f32d506d27..11635d5b5cf7b9 100644 --- a/ios/chrome/browser/BUILD.gn +++ b/ios/chrome/browser/BUILD.gn @@ -483,6 +483,11 @@ source_set("browser") { "ui/commands/show_signin_command.mm", "ui/context_menu/context_menu_coordinator.h", "ui/context_menu/context_menu_coordinator.mm", + "ui/elements/selector_coordinator.h", + "ui/elements/selector_coordinator.mm", + "ui/elements/selector_picker_view_controller.h", + "ui/elements/selector_picker_view_controller.mm", + "ui/elements/selector_view_controller_delegate.h", "ui/file_locations.h", "ui/file_locations.mm", "ui/image_util.h", diff --git a/ios/chrome/browser/ui/elements/selector_coordinator.h b/ios/chrome/browser/ui/elements/selector_coordinator.h new file mode 100644 index 00000000000000..52f5cb7dd30a4a --- /dev/null +++ b/ios/chrome/browser/ui/elements/selector_coordinator.h @@ -0,0 +1,33 @@ +// Copyright 2016 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. + +#ifndef IOS_CHROME_BROWSER_UI_ELEMENTS_SELECTOR_COORDINATOR_H_ +#define IOS_CHROME_BROWSER_UI_ELEMENTS_SELECTOR_COORDINATOR_H_ + +#import "ios/chrome/browser/chrome_coordinator.h" + +@class SelectorCoordinator; + +// Delegate protocol for SelectorCoordinator +@protocol SelectorCoordinatorDelegate +// Called when selection UI has completed. +- (void)selectorCoordinator:(nonnull SelectorCoordinator*)coordinator + didCompleteWithSelection:(nonnull NSString*)selection; +@end + +// Coordinator for displaying UI to allow the user to pick among options. +@interface SelectorCoordinator : ChromeCoordinator + +// Options to present to the user. +@property(nonatomic, nullable, assign) NSOrderedSet* options; + +// The default option. Starts out selected, and is set as the selected option +// if the user performs a cancel action. +@property(nonatomic, nullable, copy) NSString* defaultOption; + +@property(nonatomic, nullable, assign) id delegate; + +@end + +#endif // IOS_CHROME_BROWSER_UI_ELEMENTS_SELECTOR_COORDINATOR_H_ diff --git a/ios/chrome/browser/ui/elements/selector_coordinator.mm b/ios/chrome/browser/ui/elements/selector_coordinator.mm new file mode 100644 index 00000000000000..64052ec7c213fa --- /dev/null +++ b/ios/chrome/browser/ui/elements/selector_coordinator.mm @@ -0,0 +1,70 @@ +// Copyright 2016 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/elements/selector_coordinator.h" + +#import "base/mac/objc_property_releaser.h" +#import "ios/chrome/browser/ui/elements/selector_picker_view_controller.h" +#import "ios/chrome/browser/ui/elements/selector_view_controller_delegate.h" + +@interface SelectorCoordinator () { + base::mac::ObjCPropertyReleaser _propertyReleaser_SelectorCoordinator; + __unsafe_unretained id _delegate; + __unsafe_unretained NSOrderedSet* _options; +} + +// Redeclaration of infoBarPickerController as readwrite. +@property(nonatomic, nullable, retain) + SelectorPickerViewController* selectorPickerViewController; + +@end + +@implementation SelectorCoordinator + +@synthesize options = _options; +@synthesize defaultOption = _defaultOption; +@synthesize delegate = _delegate; +@synthesize selectorPickerViewController = _selectorPickerViewController; + +- (nullable instancetype)initWithBaseViewController: + (nullable UIViewController*)viewController { + self = [super initWithBaseViewController:viewController]; + if (self) { + _propertyReleaser_SelectorCoordinator.Init(self, + [SelectorCoordinator class]); + } + return self; +} + +- (void)start { + self.selectorPickerViewController = + [[SelectorPickerViewController alloc] initWithOptions:self.options + default:self.defaultOption]; + self.selectorPickerViewController.delegate = self; + // TODO(crbug.com/622244): Display via custom UIPresentionController to + // show as a bottom sheet. + self.selectorPickerViewController.modalTransitionStyle = + UIModalTransitionStyleCoverVertical; + self.selectorPickerViewController.modalPresentationStyle = + UIModalPresentationFormSheet; + [self.baseViewController + presentViewController:self.selectorPickerViewController + animated:YES + completion:nil]; +} + +- (void)stop { + [self.selectorPickerViewController dismissViewControllerAnimated:YES + completion:nil]; +} + +#pragma mark SelectorViewControllerDelegate + +- (void)selectorViewController:(UIViewController*)viewController + didSelectOption:(NSString*)option { + [self.delegate selectorCoordinator:self didCompleteWithSelection:option]; + [self stop]; +} + +@end \ No newline at end of file diff --git a/ios/chrome/browser/ui/elements/selector_coordinator_unittest.mm b/ios/chrome/browser/ui/elements/selector_coordinator_unittest.mm new file mode 100644 index 00000000000000..f454deafb36570 --- /dev/null +++ b/ios/chrome/browser/ui/elements/selector_coordinator_unittest.mm @@ -0,0 +1,70 @@ +// Copyright 2016 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/elements/selector_coordinator.h" + +#include "base/test/ios/wait_util.h" +#import "ios/chrome/browser/ui/elements/selector_picker_view_controller.h" +#import "ios/chrome/browser/ui/elements/selector_view_controller_delegate.h" +#include "testing/gtest/include/gtest/gtest.h" +#import "testing/gtest_mac.h" +#include "third_party/ocmock/OCMock/OCMock.h" +#include "third_party/ocmock/gtest_support.h" + +@interface SelectorCoordinator () +// The view controller for the picker view the coordinator presents. Exposed for +// testing. +@property SelectorPickerViewController* selectorPickerViewController; +@end + +// Tests that invoking start on the coordinator presents the selector view, and +// that invoking stop dismisses the view and invokes the delegate. +TEST(SelectorCoordinatorTest, StartAndStop) { + UIWindow* keyWindow = [[UIApplication sharedApplication] keyWindow]; + UIViewController* rootViewController = keyWindow.rootViewController; + SelectorCoordinator* coordinator = [[[SelectorCoordinator alloc] + initWithBaseViewController:rootViewController] autorelease]; + + void (^testSteps)(void) = ^{ + [coordinator start]; + EXPECT_NSEQ(coordinator.selectorPickerViewController, + rootViewController.presentedViewController); + + [coordinator stop]; + base::test::ios::WaitUntilCondition(^{ + return !rootViewController.presentedViewController; + }); + }; + // Ensure any other presented controllers are dismissed before starting the + // coordinator. + [rootViewController dismissViewControllerAnimated:NO completion:testSteps]; +} + +// Tests that calling the view controller delegate method invokes the +// SelectorCoordinatorDelegate method and stops the coordinator. +TEST(SelectorCoordinatorTest, Delegate) { + UIWindow* keyWindow = [[UIApplication sharedApplication] keyWindow]; + UIViewController* rootViewController = keyWindow.rootViewController; + SelectorCoordinator* coordinator = [[[SelectorCoordinator alloc] + initWithBaseViewController:rootViewController] autorelease]; + id delegate = + [OCMockObject mockForProtocol:@protocol(SelectorCoordinatorDelegate)]; + coordinator.delegate = delegate; + + void (^testSteps)(void) = ^{ + [coordinator start]; + NSString* testOption = @"Test Option"; + [[delegate expect] selectorCoordinator:coordinator + didCompleteWithSelection:testOption]; + [coordinator selectorViewController:coordinator.selectorPickerViewController + didSelectOption:testOption]; + base::test::ios::WaitUntilCondition(^{ + return !rootViewController.presentedViewController; + }); + }; + // Ensure any other presented controllers are dismissed before starting the + // coordinator. + [rootViewController dismissViewControllerAnimated:NO completion:testSteps]; + EXPECT_OCMOCK_VERIFY(delegate); +} \ No newline at end of file diff --git a/ios/chrome/browser/ui/elements/selector_picker_view_controller.h b/ios/chrome/browser/ui/elements/selector_picker_view_controller.h new file mode 100644 index 00000000000000..8a957e80c9a492 --- /dev/null +++ b/ios/chrome/browser/ui/elements/selector_picker_view_controller.h @@ -0,0 +1,30 @@ +// Copyright 2016 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. + +#ifndef IOS_CHROME_BROWSER_UI_ELEMENTS_SELECTOR_PICKER_VIEW_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_UI_ELEMENTS_SELECTOR_PICKER_VIEW_CONTROLLER_H_ + +#import + +@protocol SelectorViewControllerDelegate; + +// View controller for displaying a UIPickerView topped by a UINavigationBar +// displaying "Done" on the right and "Cancel" on the left. +@interface SelectorPickerViewController : UIViewController + +// Initializer for view controller that will display |options|. |defaultOptions| +// will be selected initially, and pressing cancel will set |defaultOption| as +// the selected option. +- (instancetype)initWithOptions:(NSOrderedSet*)options + default:(NSString*)defaultOption + NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithNibName:(NSString*)nibNameOrNil + bundle:(NSBundle*)nibBundleOrNil NS_UNAVAILABLE; +- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE; + +@property(nonatomic, weak) id delegate; + +@end + +#endif // IOS_CHROME_BROWSER_UI_ELEMENTS_SELECTOR_PICKER_VIEW_CONTROLLER_H_ diff --git a/ios/chrome/browser/ui/elements/selector_picker_view_controller.mm b/ios/chrome/browser/ui/elements/selector_picker_view_controller.mm new file mode 100644 index 00000000000000..b2788bb17eca86 --- /dev/null +++ b/ios/chrome/browser/ui/elements/selector_picker_view_controller.mm @@ -0,0 +1,157 @@ +// Copyright 2016 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/elements/selector_picker_view_controller.h" + +#import "ios/chrome/browser/ui/elements/selector_view_controller_delegate.h" +#include "base/logging.h" +#import "base/mac/objc_property_releaser.h" + +namespace { +// Font size of text in the picker view. +CGFloat kUIPickerFontSize = 26; +} // namespace + +@interface SelectorPickerViewController () { + base::mac::ObjCPropertyReleaser + _propertyReleaser_SelectorPickerViewController; + __unsafe_unretained id _delegate; +} +// Options to display. +@property(nonatomic, copy) NSOrderedSet* options; +// The default option. +@property(nonatomic, copy) NSString* defaultOption; +// The displayed UINavigationBar. Exposed for testing. +@property(nonatomic, retain) UINavigationBar* navigationBar; +// The displayed UIPickerView. Exposed for testing. +@property(nonatomic, retain) UIPickerView* pickerView; +// Action for the "Done" button. +- (void)doneButtonPressed; +// Action for the "Cancel" button. +- (void)cancelButtonPressed; +@end + +@implementation SelectorPickerViewController + +@synthesize pickerView = _pickerView; +@synthesize navigationBar = _navigationBar; + +@synthesize options = _options; +@synthesize defaultOption = _defaultOption; + +- (instancetype)initWithOptions:(NSOrderedSet*)options + default:(NSString*)defaultOption { + self = [super initWithNibName:nil bundle:nil]; + if (self) { + _propertyReleaser_SelectorPickerViewController.Init( + self, [SelectorPickerViewController class]); + _options = [options copy]; + _defaultOption = [defaultOption copy]; + } + return self; +} + +- (instancetype)initWithNibName:(NSString*)nibName bundle:(NSBundle*)nibBundle { + NOTREACHED(); + return nil; +} + +- (instancetype)initWithCoder:(NSCoder*)aDecoder { + NOTREACHED(); + return nil; +} + +- (void)loadView { + self.pickerView = [[UIPickerView alloc] initWithFrame:CGRectZero]; + self.navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectZero]; + self.pickerView.translatesAutoresizingMaskIntoConstraints = NO; + self.navigationBar.translatesAutoresizingMaskIntoConstraints = NO; + UIStackView* stackView = [[[UIStackView alloc] + initWithArrangedSubviews:@[ self.navigationBar, self.pickerView ]] + autorelease]; + stackView.axis = UILayoutConstraintAxisVertical; + stackView.translatesAutoresizingMaskIntoConstraints = NO; + self.view = stackView; +} + +- (void)viewDidLoad { + self.view.backgroundColor = [UIColor whiteColor]; + + self.pickerView.showsSelectionIndicator = YES; + self.pickerView.backgroundColor = [UIColor whiteColor]; + self.pickerView.delegate = self; + self.pickerView.dataSource = self; + NSInteger initialIndex = [self.options indexOfObject:self.defaultOption]; + if (initialIndex != NSNotFound) { + [self.pickerView selectRow:initialIndex inComponent:0 animated:NO]; + } + + UINavigationItem* navigationItem = + [[[UINavigationItem alloc] initWithTitle:@""] autorelease]; + UIBarButtonItem* doneButton = [[[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemDone + target:nil + action:@selector(doneButtonPressed)] autorelease]; + UIBarButtonItem* cancelButton = [[[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemCancel + target:nil + action:@selector(cancelButtonPressed)] autorelease]; + [navigationItem setRightBarButtonItem:doneButton]; + [navigationItem setLeftBarButtonItem:cancelButton]; + [navigationItem setHidesBackButton:YES]; + [self.navigationBar pushNavigationItem:navigationItem animated:NO]; +} + +- (id)delegate { + return _delegate; +} + +- (void)setDelegate:(id)delegate { + _delegate = delegate; +} + +#pragma mark UIPickerViewDataSource + +- (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView { + return 1; +} + +- (NSInteger)pickerView:(UIPickerView*)pickerView + numberOfRowsInComponent:(NSInteger)component { + return [self.options count]; +} + +#pragma mark UIPickerViewDelegate + +- (UIView*)pickerView:(UIPickerView*)pickerView + viewForRow:(NSInteger)row + forComponent:(NSInteger)component + reusingView:(UIView*)view { + DCHECK_EQ(0, component); + UILabel* label = [view isKindOfClass:[UILabel class]] + ? (UILabel*)view + : [[[UILabel alloc] init] autorelease]; + NSString* text = self.options[row]; + label.text = text; + label.textAlignment = NSTextAlignmentCenter; + label.font = [text isEqualToString:self.defaultOption] + ? [UIFont boldSystemFontOfSize:kUIPickerFontSize] + : [UIFont systemFontOfSize:kUIPickerFontSize]; + return label; +} + +#pragma mark Private methods + +- (void)doneButtonPressed { + NSInteger selectedIndex = [self.pickerView selectedRowInComponent:0]; + [_delegate selectorViewController:self + didSelectOption:self.options[selectedIndex]]; +} + +- (void)cancelButtonPressed { + [_delegate selectorViewController:self didSelectOption:self.defaultOption]; +} + +@end diff --git a/ios/chrome/browser/ui/elements/selector_picker_view_controller_unittest.mm b/ios/chrome/browser/ui/elements/selector_picker_view_controller_unittest.mm new file mode 100644 index 00000000000000..219f9b4f819f77 --- /dev/null +++ b/ios/chrome/browser/ui/elements/selector_picker_view_controller_unittest.mm @@ -0,0 +1,112 @@ +// Copyright 2016 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/elements/selector_picker_view_controller.h" + +#include "base/mac/foundation_util.h" +#import "ios/chrome/browser/ui/elements/selector_view_controller_delegate.h" +#include "testing/gtest/include/gtest/gtest.h" +#import "testing/gtest_mac.h" +#include "third_party/ocmock/OCMock/OCMock.h" +#include "third_party/ocmock/gtest_support.h" + +@interface SelectorPickerViewController () +// The displayed UINavigationBar. Exposed for testing. +@property(nonatomic, retain) UINavigationBar* navigationBar; +// The displayed UIPickerView. Exposed for testing. +@property(nonatomic, retain) UIPickerView* pickerView; +@end + +// Test that invoking the right bar button action ("Done") invokes the delegate +// callback with the appropriate selected item. +TEST(SelectorPickerViewControllerTest, Done) { + NSString* option1 = @"Option 1"; + NSString* option2 = @"Option 2"; + NSOrderedSet* options = + [NSOrderedSet orderedSetWithArray:@[ option1, option2 ]]; + SelectorPickerViewController* selector_picker_view_controller = + [[[SelectorPickerViewController alloc] initWithOptions:options + default:option1] + autorelease]; + id delegate = + [OCMockObject mockForProtocol:@protocol(SelectorViewControllerDelegate)]; + [[delegate expect] selectorViewController:selector_picker_view_controller + didSelectOption:option2]; + selector_picker_view_controller.delegate = delegate; + [selector_picker_view_controller loadView]; + [selector_picker_view_controller viewDidLoad]; + + [selector_picker_view_controller.pickerView selectRow:1 + inComponent:0 + animated:NO]; + UIBarButtonItem* rightButton = + selector_picker_view_controller.navigationBar.topItem.rightBarButtonItem; + [selector_picker_view_controller performSelector:rightButton.action]; + EXPECT_OCMOCK_VERIFY(delegate); +} + +// Test that invoking the right bar button action ("Cancel") invokes the +// delegate callback with the default item. +TEST(SelectorPickerViewControllerTest, Cancel) { + NSString* option1 = @"Option 1"; + NSString* option2 = @"Option 2"; + NSOrderedSet* options = + [NSOrderedSet orderedSetWithArray:@[ option1, option2 ]]; + SelectorPickerViewController* selector_picker_view_controller = + [[[SelectorPickerViewController alloc] initWithOptions:options + default:option2] + autorelease]; + id delegate = + [OCMockObject mockForProtocol:@protocol(SelectorViewControllerDelegate)]; + [[delegate expect] selectorViewController:selector_picker_view_controller + didSelectOption:option2]; + selector_picker_view_controller.delegate = delegate; + [selector_picker_view_controller loadView]; + [selector_picker_view_controller viewDidLoad]; + + [selector_picker_view_controller.pickerView selectRow:1 + inComponent:0 + animated:NO]; + UIBarButtonItem* leftButton = + selector_picker_view_controller.navigationBar.topItem.leftBarButtonItem; + [selector_picker_view_controller performSelector:leftButton.action]; + EXPECT_OCMOCK_VERIFY(delegate); +} + +// Test that the picker view is styled appropriately based on parameters +// provided at initialization. +TEST(SelectorPickerViewControllerTest, DefaultStyling) { + NSString* option1 = @"Option 1"; + NSString* option2 = @"Option 2"; + NSString* option3 = @"Option 3"; + NSOrderedSet* options = + [NSOrderedSet orderedSetWithArray:@[ option1, option2, option3 ]]; + SelectorPickerViewController* selector_picker_view_controller = + [[[SelectorPickerViewController alloc] initWithOptions:options + default:option2] + autorelease]; + [selector_picker_view_controller loadView]; + [selector_picker_view_controller viewDidLoad]; + + // Row 2 (index 1), the default should be selected be bolded. + EXPECT_EQ( + 1, [selector_picker_view_controller.pickerView selectedRowInComponent:0]); + UILabel* row2 = base::mac::ObjCCastStrict( + [selector_picker_view_controller.pickerView viewForRow:1 forComponent:0]); + EXPECT_NSEQ(option2, row2.text); + EXPECT_TRUE(row2.font.fontDescriptor.symbolicTraits & + UIFontDescriptorTraitBold); + + // Rows 1 and 3 should not be bold. + UILabel* row1 = base::mac::ObjCCastStrict( + [selector_picker_view_controller.pickerView viewForRow:0 forComponent:0]); + EXPECT_NSEQ(option1, row1.text); + EXPECT_FALSE(row1.font.fontDescriptor.symbolicTraits & + UIFontDescriptorTraitBold); + UILabel* row3 = base::mac::ObjCCastStrict( + [selector_picker_view_controller.pickerView viewForRow:2 forComponent:0]); + EXPECT_NSEQ(option3, row3.text); + EXPECT_FALSE(row3.font.fontDescriptor.symbolicTraits & + UIFontDescriptorTraitBold); +} diff --git a/ios/chrome/browser/ui/elements/selector_view_controller_delegate.h b/ios/chrome/browser/ui/elements/selector_view_controller_delegate.h new file mode 100644 index 00000000000000..5e0a801780325e --- /dev/null +++ b/ios/chrome/browser/ui/elements/selector_view_controller_delegate.h @@ -0,0 +1,16 @@ +// Copyright 2016 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. + +#ifndef IOS_CHROME_BROWSER_UI_ELEMENTS_SELECTOR_VIEW_CONTROLLER_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_ELEMENTS_SELECTOR_VIEW_CONTROLLER_DELEGATE_H_ + +// Protocol for delegates of view controllers presented by SelectorCoordinator. +@protocol SelectorViewControllerDelegate +// Invoked when an option has been selected, or the user otherwise dismisses +// the UI. +- (void)selectorViewController:(UIViewController*)viewController + didSelectOption:(NSString*)option; +@end + +#endif // IOS_CHROME_BROWSER_UI_ELEMENTS_SELECTOR_VIEW_CONTROLLER_DELEGATE_H_ diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp index 1d43c70807903c..7888643265462e 100644 --- a/ios/chrome/ios_chrome.gyp +++ b/ios/chrome/ios_chrome.gyp @@ -25,10 +25,10 @@ ], }, 'sources': [ - 'app/application_delegate/memory_warning_helper.h', - 'app/application_delegate/memory_warning_helper.mm', 'app/UIApplication+ExitsOnSuspend.h', 'app/UIApplication+ExitsOnSuspend.mm', + 'app/application_delegate/memory_warning_helper.h', + 'app/application_delegate/memory_warning_helper.mm', 'app/deferred_initialization_runner.h', 'app/deferred_initialization_runner.mm', 'app/safe_mode_crashing_modules_config.h', @@ -411,8 +411,8 @@ 'browser/net/proxy_service_factory.h', 'browser/net/retryable_url_fetcher.h', 'browser/net/retryable_url_fetcher.mm', - 'browser/notification_promo.h', 'browser/notification_promo.cc', + 'browser/notification_promo.h', 'browser/ntp_snippets/ios_chrome_ntp_snippets_service_factory.cc', 'browser/ntp_snippets/ios_chrome_ntp_snippets_service_factory.h', 'browser/open_from_clipboard/create_clipboard_recent_content.h', @@ -464,11 +464,11 @@ 'browser/reading_list/reading_list_entry.h', 'browser/reading_list/reading_list_model.cc', 'browser/reading_list/reading_list_model.h', + 'browser/reading_list/reading_list_model_factory.cc', + 'browser/reading_list/reading_list_model_factory.h', 'browser/reading_list/reading_list_model_impl.cc', 'browser/reading_list/reading_list_model_impl.h', 'browser/reading_list/reading_list_model_observer.h', - 'browser/reading_list/reading_list_model_factory.cc', - 'browser/reading_list/reading_list_model_factory.h', 'browser/reading_list/reading_list_model_observer.h', 'browser/reading_list/reading_list_model_storage.h', 'browser/reading_list/reading_list_model_storage_defaults.h', @@ -620,6 +620,11 @@ 'browser/ui/commands/show_signin_command.mm', 'browser/ui/context_menu/context_menu_coordinator.h', 'browser/ui/context_menu/context_menu_coordinator.mm', + 'browser/ui/elements/selector_coordinator.h', + 'browser/ui/elements/selector_coordinator.mm', + 'browser/ui/elements/selector_picker_view_controller.h', + 'browser/ui/elements/selector_picker_view_controller.mm', + 'browser/ui/elements/selector_view_controller_delegate.h', 'browser/ui/file_locations.h', 'browser/ui/file_locations.mm', 'browser/ui/image_util.h', diff --git a/ios/chrome/ios_chrome_tests.gyp b/ios/chrome/ios_chrome_tests.gyp index 1f94d424b2ee9a..c3432d37dbe138 100644 --- a/ios/chrome/ios_chrome_tests.gyp +++ b/ios/chrome/ios_chrome_tests.gyp @@ -73,6 +73,8 @@ 'browser/translate/translate_service_ios_unittest.cc', 'browser/ui/commands/set_up_for_testing_command_unittest.mm', 'browser/ui/context_menu/context_menu_coordinator_unittest.mm', + 'browser/ui/elements/selector_coordinator_unittest.mm', + 'browser/ui/elements/selector_picker_view_controller_unittest.mm', 'browser/ui/keyboard/UIKeyCommand+ChromeTest.mm', 'browser/ui/keyboard/hardware_keyboard_watcher_unittest.mm', 'browser/ui/native_content_controller_unittest.mm',