OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #import "ios/chrome/browser/ui/settings/settings_root_collection_view_controller
.h" |
| 6 |
| 7 #include "base/ios/ios_util.h" |
| 8 #include "base/logging.h" |
| 9 #import "base/mac/foundation_util.h" |
| 10 #include "base/mac/objc_property_releaser.h" |
| 11 #include "base/mac/scoped_nsobject.h" |
| 12 #import "ios/chrome/browser/browser_state/chrome_browser_state.h" |
| 13 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" |
| 14 #include "ios/chrome/browser/ui/commands/ios_command_ids.h" |
| 15 #import "ios/chrome/browser/ui/commands/open_url_command.h" |
| 16 #include "ios/chrome/browser/ui/settings/bar_button_activity_indicator.h" |
| 17 #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" |
| 18 #import "ios/chrome/browser/ui/settings/settings_utils.h" |
| 19 #include "ios/chrome/browser/ui/ui_util.h" |
| 20 #import "ios/chrome/browser/ui/uikit_ui_util.h" |
| 21 #include "ios/chrome/grit/ios_strings.h" |
| 22 #import "ios/third_party/material_components_ios/src/components/Collections/src/
MaterialCollections.h" |
| 23 #include "ui/base/l10n/l10n_util.h" |
| 24 |
| 25 namespace { |
| 26 enum SavedBarButtomItemPositionEnum { |
| 27 kUndefinedBarButtonItemPosition, |
| 28 kLeftBarButtonItemPosition, |
| 29 kRightBarButtonItemPosition |
| 30 }; |
| 31 |
| 32 // Dimension of the authentication operation activity indicator frame. |
| 33 const CGFloat kActivityIndicatorDimensionIPad = 64; |
| 34 const CGFloat kActivityIndicatorDimensionIPhone = 56; |
| 35 |
| 36 } // namespace |
| 37 |
| 38 @implementation SettingsRootCollectionViewController { |
| 39 SavedBarButtomItemPositionEnum savedBarButtonItemPosition_; |
| 40 base::scoped_nsobject<UIBarButtonItem> savedBarButtonItem_; |
| 41 base::scoped_nsobject<UIView> veil_; |
| 42 |
| 43 base::mac::ObjCPropertyReleaser |
| 44 propertyReleaser_SettingsRootCollectionViewController_; |
| 45 } |
| 46 |
| 47 @synthesize shouldHideDoneButton = shouldHideDoneButton_; |
| 48 @synthesize collectionViewAccessibilityIdentifier = |
| 49 collectionViewAccessibilityIdentifier_; |
| 50 |
| 51 - (instancetype)initWithStyle:(CollectionViewControllerStyle)style { |
| 52 self = [super initWithStyle:style]; |
| 53 if (self) { |
| 54 propertyReleaser_SettingsRootCollectionViewController_.Init( |
| 55 self, [SettingsRootCollectionViewController class]); |
| 56 } |
| 57 return self; |
| 58 } |
| 59 |
| 60 - (void)viewDidLoad { |
| 61 [super viewDidLoad]; |
| 62 self.collectionView.accessibilityIdentifier = |
| 63 self.collectionViewAccessibilityIdentifier; |
| 64 |
| 65 // Customize collection view settings. |
| 66 self.styler.cellStyle = MDCCollectionViewCellStyleCard; |
| 67 self.styler.separatorInset = UIEdgeInsetsMake(0, 16, 0, 16); |
| 68 } |
| 69 |
| 70 - (void)viewWillAppear:(BOOL)animated { |
| 71 [super viewWillAppear:animated]; |
| 72 UIBarButtonItem* doneButton = [self doneButtonIfNeeded]; |
| 73 if (!self.navigationItem.rightBarButtonItem && doneButton) { |
| 74 self.navigationItem.rightBarButtonItem = doneButton; |
| 75 } |
| 76 } |
| 77 |
| 78 - (UIBarButtonItem*)doneButtonIfNeeded { |
| 79 if (self.shouldHideDoneButton) { |
| 80 return nil; |
| 81 } |
| 82 SettingsNavigationController* navigationController = |
| 83 base::mac::ObjCCast<SettingsNavigationController>( |
| 84 self.navigationController); |
| 85 return [navigationController doneButton]; |
| 86 } |
| 87 |
| 88 - (UIBarButtonItem*)createEditButton { |
| 89 // Create a custom Edit bar button item, as Material Navigation Bar does not |
| 90 // handle a system UIBarButtonSystemItemEdit item. |
| 91 UIBarButtonItem* button = [[[UIBarButtonItem alloc] |
| 92 initWithTitle:l10n_util::GetNSString(IDS_IOS_NAVIGATION_BAR_EDIT_BUTTON) |
| 93 style:UIBarButtonItemStyleDone |
| 94 target:self |
| 95 action:@selector(editButtonPressed)] autorelease]; |
| 96 [button setEnabled:[self editButtonEnabled]]; |
| 97 return button; |
| 98 } |
| 99 |
| 100 - (UIBarButtonItem*)createEditDoneButton { |
| 101 // Create a custom Done bar button item, as Material Navigation Bar does not |
| 102 // handle a system UIBarButtonSystemItemDone item. |
| 103 return [[[UIBarButtonItem alloc] |
| 104 initWithTitle:l10n_util::GetNSString(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON) |
| 105 style:UIBarButtonItemStyleDone |
| 106 target:self |
| 107 action:@selector(editButtonPressed)] autorelease]; |
| 108 } |
| 109 |
| 110 - (void)updateEditButton { |
| 111 if ([self.editor isEditing]) { |
| 112 self.navigationItem.rightBarButtonItem = [self createEditDoneButton]; |
| 113 } else if ([self shouldShowEditButton]) { |
| 114 self.navigationItem.rightBarButtonItem = [self createEditButton]; |
| 115 } else { |
| 116 self.navigationItem.rightBarButtonItem = [self doneButtonIfNeeded]; |
| 117 } |
| 118 } |
| 119 |
| 120 - (void)editButtonPressed { |
| 121 [self.editor setEditing:![self.editor isEditing] animated:YES]; |
| 122 [self updateEditButton]; |
| 123 } |
| 124 |
| 125 - (void)reloadData { |
| 126 [self loadModel]; |
| 127 [self.collectionView reloadData]; |
| 128 } |
| 129 |
| 130 #pragma mark - CollectionViewFooterLinkDelegate |
| 131 |
| 132 - (void)cell:(CollectionViewFooterCell*)cell didTapLinkURL:(GURL)URL { |
| 133 base::scoped_nsobject<OpenUrlCommand> command( |
| 134 [[OpenUrlCommand alloc] initWithURLFromChrome:URL]); |
| 135 [command setTag:IDC_CLOSE_SETTINGS_AND_OPEN_URL]; |
| 136 [self chromeExecuteCommand:command]; |
| 137 } |
| 138 |
| 139 #pragma mark - Status bar |
| 140 |
| 141 - (UIViewController*)childViewControllerForStatusBarHidden { |
| 142 if (!base::ios::IsRunningOnIOS10OrLater()) { |
| 143 // TODO(crbug.com/620361): Remove the entire method override when iOS 9 is |
| 144 // dropped. |
| 145 return nil; |
| 146 } else { |
| 147 return [super childViewControllerForStatusBarHidden]; |
| 148 } |
| 149 } |
| 150 |
| 151 - (BOOL)prefersStatusBarHidden { |
| 152 if (!base::ios::IsRunningOnIOS10OrLater()) { |
| 153 // TODO(crbug.com/620361): Remove the entire method override when iOS 9 is |
| 154 // dropped. |
| 155 return NO; |
| 156 } else { |
| 157 return [super prefersStatusBarHidden]; |
| 158 } |
| 159 } |
| 160 |
| 161 - (UIViewController*)childViewControllerForStatusBarStyle { |
| 162 if (!base::ios::IsRunningOnIOS10OrLater()) { |
| 163 // TODO(crbug.com/620361): Remove the entire method override when iOS 9 is |
| 164 // dropped. |
| 165 return nil; |
| 166 } else { |
| 167 return [super childViewControllerForStatusBarStyle]; |
| 168 } |
| 169 } |
| 170 |
| 171 - (UIStatusBarStyle)preferredStatusBarStyle { |
| 172 if (!base::ios::IsRunningOnIOS10OrLater()) { |
| 173 // TODO(crbug.com/620361): Remove the entire method override when iOS 9 is |
| 174 // dropped. |
| 175 if (IsIPadIdiom() && !IsCompact()) { |
| 176 return UIStatusBarStyleLightContent; |
| 177 } else { |
| 178 return UIStatusBarStyleDefault; |
| 179 } |
| 180 } else { |
| 181 return [super preferredStatusBarStyle]; |
| 182 } |
| 183 } |
| 184 |
| 185 #pragma mark - Subclassing |
| 186 |
| 187 - (BOOL)shouldShowEditButton { |
| 188 return NO; |
| 189 } |
| 190 |
| 191 - (BOOL)editButtonEnabled { |
| 192 return NO; |
| 193 } |
| 194 |
| 195 - (void)preventUserInteraction { |
| 196 DCHECK(!savedBarButtonItem_); |
| 197 DCHECK_EQ(kUndefinedBarButtonItemPosition, savedBarButtonItemPosition_); |
| 198 |
| 199 // Create |waitButton|. |
| 200 BOOL displayActivityIndicatorOnTheRight = |
| 201 self.navigationItem.rightBarButtonItem != nil; |
| 202 CGFloat activityIndicatorDimension = IsIPadIdiom() |
| 203 ? kActivityIndicatorDimensionIPad |
| 204 : kActivityIndicatorDimensionIPhone; |
| 205 base::scoped_nsobject<BarButtonActivityIndicator> indicator( |
| 206 [[BarButtonActivityIndicator alloc] |
| 207 initWithFrame:CGRectMake(0.0, 0.0, activityIndicatorDimension, |
| 208 activityIndicatorDimension)]); |
| 209 base::scoped_nsobject<UIBarButtonItem> waitButton( |
| 210 [[UIBarButtonItem alloc] initWithCustomView:indicator]); |
| 211 |
| 212 if (displayActivityIndicatorOnTheRight) { |
| 213 // If there is a right bar button item, then it is the "Done" button. |
| 214 savedBarButtonItem_.reset([self.navigationItem.rightBarButtonItem retain]); |
| 215 savedBarButtonItemPosition_ = kRightBarButtonItemPosition; |
| 216 self.navigationItem.rightBarButtonItem = waitButton; |
| 217 [self.navigationItem.leftBarButtonItem setEnabled:NO]; |
| 218 } else { |
| 219 savedBarButtonItem_.reset([self.navigationItem.leftBarButtonItem retain]); |
| 220 savedBarButtonItemPosition_ = kLeftBarButtonItemPosition; |
| 221 self.navigationItem.leftBarButtonItem = waitButton; |
| 222 } |
| 223 |
| 224 // Adds a veil that covers the collection view and prevents user interaction. |
| 225 DCHECK(self.view); |
| 226 DCHECK(!veil_); |
| 227 veil_.reset([[UIView alloc] initWithFrame:self.view.bounds]); |
| 228 [veil_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | |
| 229 UIViewAutoresizingFlexibleHeight)]; |
| 230 [veil_ setBackgroundColor:[UIColor colorWithWhite:1.0 alpha:0.5]]; |
| 231 [self.view addSubview:veil_]; |
| 232 |
| 233 // Disable user interaction for the navigation controller view to ensure |
| 234 // that the user cannot go back by swipping the navigation's top view |
| 235 // controller |
| 236 [self.navigationController.view setUserInteractionEnabled:NO]; |
| 237 } |
| 238 |
| 239 - (void)allowUserInteraction { |
| 240 DCHECK(self.navigationController) |
| 241 << "|allowUserInteraction| should always be called before this settings" |
| 242 " controller is popped or dismissed."; |
| 243 [self.navigationController.view setUserInteractionEnabled:YES]; |
| 244 |
| 245 // Removes the veil that prevents user interaction. |
| 246 DCHECK(veil_); |
| 247 [UIView animateWithDuration:0.3 |
| 248 animations:^{ |
| 249 [veil_ removeFromSuperview]; |
| 250 } |
| 251 completion:^(BOOL finished) { |
| 252 veil_.reset(); |
| 253 }]; |
| 254 |
| 255 DCHECK(savedBarButtonItem_); |
| 256 switch (savedBarButtonItemPosition_) { |
| 257 case kLeftBarButtonItemPosition: |
| 258 self.navigationItem.leftBarButtonItem = savedBarButtonItem_; |
| 259 break; |
| 260 case kRightBarButtonItemPosition: |
| 261 self.navigationItem.rightBarButtonItem = savedBarButtonItem_; |
| 262 [self.navigationItem.leftBarButtonItem setEnabled:YES]; |
| 263 break; |
| 264 default: |
| 265 NOTREACHED(); |
| 266 break; |
| 267 } |
| 268 savedBarButtonItem_.reset(); |
| 269 savedBarButtonItemPosition_ = kUndefinedBarButtonItemPosition; |
| 270 } |
| 271 |
| 272 @end |
OLD | NEW |