OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 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/bookmarks/bars/bookmark_navigation_bar.h" |
| 6 |
| 7 #import <QuartzCore/QuartzCore.h> |
| 8 |
| 9 #include "base/mac/objc_property_releaser.h" |
| 10 #include "base/mac/scoped_nsobject.h" |
| 11 #import "ios/chrome/browser/ui/bookmarks/bookmark_extended_button.h" |
| 12 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" |
| 13 #import "ios/chrome/browser/ui/rtl_geometry.h" |
| 14 #include "ios/chrome/browser/ui/ui_util.h" |
| 15 #include "ios/chrome/grit/ios_strings.h" |
| 16 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" |
| 17 #include "ui/base/l10n/l10n_util.h" |
| 18 |
| 19 namespace { |
| 20 const CGFloat kButtonHeight = 24; |
| 21 const CGFloat kButtonWidth = 24; |
| 22 |
| 23 // The height of the content, not including possible extra space for the status |
| 24 // bar. |
| 25 const CGFloat kContentHeight = 56; |
| 26 // The distance between buttons. |
| 27 const CGFloat kInterButtonMargin = 24; |
| 28 }; // namespace |
| 29 |
| 30 @interface BookmarkNavigationBar () { |
| 31 base::mac::ObjCPropertyReleaser _propertyReleaser_BookmarkNavigationBar; |
| 32 } |
| 33 @property(nonatomic, retain) BookmarkExtendedButton* cancelButton; |
| 34 // All subviews are added to |contentView|, which allows easy repositioning of |
| 35 // the content to account for iOS 6 and iOS 7+ layout differences. |
| 36 @property(nonatomic, retain) UIView* contentView; |
| 37 @property(nonatomic, retain) BookmarkExtendedButton* backButton; |
| 38 @property(nonatomic, retain) BookmarkExtendedButton* editButton; |
| 39 @property(nonatomic, retain) BookmarkExtendedButton* menuButton; |
| 40 @property(nonatomic, retain) UILabel* titleLabel; |
| 41 @end |
| 42 |
| 43 @implementation BookmarkNavigationBar |
| 44 @synthesize backButton = _backButton; |
| 45 @synthesize cancelButton = _cancelButton; |
| 46 @synthesize contentView = _contentView; |
| 47 @synthesize editButton = _editButton; |
| 48 @synthesize menuButton = _menuButton; |
| 49 @synthesize titleLabel = _titleLabel; |
| 50 |
| 51 - (id)initWithFrame:(CGRect)outerFrame { |
| 52 self = [super initWithFrame:outerFrame]; |
| 53 if (self) { |
| 54 _propertyReleaser_BookmarkNavigationBar.Init(self, |
| 55 [BookmarkNavigationBar class]); |
| 56 |
| 57 self.backgroundColor = bookmark_utils_ios::mainBackgroundColor(); |
| 58 self.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | |
| 59 UIViewAutoresizingFlexibleWidth; |
| 60 |
| 61 // Position the content view at the bottom of |self|. |
| 62 CGFloat contentY = CGRectGetHeight(outerFrame) - kContentHeight; |
| 63 self.contentView = base::scoped_nsobject<UIView>([[UIView alloc] |
| 64 initWithFrame:CGRectMake(0, contentY, CGRectGetWidth(outerFrame), |
| 65 kContentHeight)]); |
| 66 [self addSubview:self.contentView]; |
| 67 self.contentView.backgroundColor = [UIColor clearColor]; |
| 68 self.contentView.autoresizingMask = |
| 69 UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth; |
| 70 CGRect contentViewBounds = self.contentView.bounds; |
| 71 |
| 72 base::scoped_nsobject<UILabel> label([[UILabel alloc] init]); |
| 73 self.titleLabel = label; |
| 74 self.titleLabel.textColor = [UIColor colorWithWhite:68 / 255.0 alpha:1.0]; |
| 75 self.titleLabel.backgroundColor = [UIColor clearColor]; |
| 76 self.titleLabel.font = [MDCTypography titleFont]; |
| 77 [self.contentView addSubview:self.titleLabel]; |
| 78 |
| 79 // The buttons should be on the right side of the screen. |
| 80 CGFloat buttonVerticalMargin = |
| 81 floor((CGRectGetHeight(contentViewBounds) - kButtonHeight) / 2); |
| 82 CGFloat buttonSideMargin = buttonVerticalMargin; |
| 83 if (IsIPadIdiom()) |
| 84 buttonSideMargin = kInterButtonMargin; |
| 85 |
| 86 CGFloat buttonX = CGRectGetWidth(contentViewBounds) - buttonSideMargin; |
| 87 |
| 88 if (!IsIPadIdiom()) { |
| 89 base::scoped_nsobject<BookmarkExtendedButton> button( |
| 90 [[BookmarkExtendedButton alloc] initWithFrame:CGRectZero]); |
| 91 |
| 92 self.cancelButton = button; |
| 93 self.cancelButton.autoresizingMask = |
| 94 UIViewAutoresizingFlexibleLeadingMargin(); |
| 95 self.cancelButton.backgroundColor = [UIColor clearColor]; |
| 96 [self.cancelButton |
| 97 setTitle:l10n_util::GetNSString(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON) |
| 98 .uppercaseString |
| 99 forState:UIControlStateNormal]; |
| 100 [self.cancelButton |
| 101 setTitleColor:[UIColor colorWithWhite:68 / 255.0 alpha:1.0] |
| 102 forState:UIControlStateNormal]; |
| 103 [[self.cancelButton titleLabel] setFont:[MDCTypography buttonFont]]; |
| 104 self.cancelButton.accessibilityLabel = |
| 105 l10n_util::GetNSString(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON); |
| 106 self.cancelButton.accessibilityIdentifier = @"Exit"; |
| 107 |
| 108 // Size the button. |
| 109 [self.cancelButton sizeToFit]; |
| 110 buttonX = buttonX - CGRectGetWidth(self.cancelButton.bounds); |
| 111 LayoutRect cancelButtonLayout = LayoutRectMake( |
| 112 buttonX, CGRectGetWidth(self.bounds), buttonVerticalMargin, |
| 113 CGRectGetWidth(self.cancelButton.bounds), kButtonHeight); |
| 114 self.cancelButton.frame = LayoutRectGetRect(cancelButtonLayout); |
| 115 self.cancelButton.extendedEdges = |
| 116 UIEdgeInsetsMake(buttonVerticalMargin, kInterButtonMargin / 2.0, |
| 117 buttonVerticalMargin, buttonSideMargin); |
| 118 |
| 119 [self.contentView addSubview:self.cancelButton]; |
| 120 |
| 121 buttonX = buttonX - kInterButtonMargin; |
| 122 } |
| 123 |
| 124 CGRect buttonFrame = LayoutRectGetRect( |
| 125 LayoutRectMake(buttonX - kButtonWidth, CGRectGetWidth(self.bounds), |
| 126 buttonVerticalMargin, kButtonWidth, kButtonHeight)); |
| 127 UIEdgeInsets buttonInsets = |
| 128 UIEdgeInsetsMake(buttonVerticalMargin, kInterButtonMargin / 2.0, |
| 129 buttonVerticalMargin, kInterButtonMargin / 2.0); |
| 130 |
| 131 base::scoped_nsobject<BookmarkExtendedButton> editButton( |
| 132 [[BookmarkExtendedButton alloc] initWithFrame:buttonFrame]); |
| 133 self.editButton = editButton; |
| 134 self.editButton.extendedEdges = buttonInsets; |
| 135 self.editButton.autoresizingMask = |
| 136 UIViewAutoresizingFlexibleLeadingMargin(); |
| 137 self.editButton.backgroundColor = [UIColor clearColor]; |
| 138 UIImage* editImage = [UIImage imageNamed:@"bookmark_gray_edit"]; |
| 139 [self.editButton setBackgroundImage:editImage |
| 140 forState:UIControlStateNormal]; |
| 141 self.editButton.accessibilityLabel = |
| 142 l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_EDIT_BUTTON_LABEL); |
| 143 self.editButton.accessibilityIdentifier = @"Edit_navigation_bar"; |
| 144 [self.contentView addSubview:self.editButton]; |
| 145 |
| 146 CGRect leftButtonFrame = LayoutRectGetRect( |
| 147 LayoutRectMake(buttonSideMargin, CGRectGetWidth(self.bounds), |
| 148 buttonVerticalMargin, kButtonWidth, kButtonHeight)); |
| 149 UIEdgeInsets leftButtonInsets = |
| 150 UIEdgeInsetsMake(buttonVerticalMargin, buttonSideMargin, |
| 151 buttonVerticalMargin, buttonSideMargin); |
| 152 |
| 153 base::scoped_nsobject<BookmarkExtendedButton> menuButton( |
| 154 [[BookmarkExtendedButton alloc] initWithFrame:leftButtonFrame]); |
| 155 self.menuButton = menuButton; |
| 156 self.menuButton.extendedEdges = leftButtonInsets; |
| 157 self.menuButton.autoresizingMask = |
| 158 UIViewAutoresizingFlexibleTrailingMargin(); |
| 159 self.menuButton.backgroundColor = [UIColor clearColor]; |
| 160 UIImage* menuImage = [UIImage imageNamed:@"bookmark_gray_menu"]; |
| 161 [self.menuButton setBackgroundImage:menuImage |
| 162 forState:UIControlStateNormal]; |
| 163 self.menuButton.accessibilityLabel = |
| 164 l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_MENU_LABEL); |
| 165 self.menuButton.accessibilityIdentifier = @"Menu"; |
| 166 [self.contentView addSubview:self.menuButton]; |
| 167 self.menuButton.hidden = YES; |
| 168 base::scoped_nsobject<BookmarkExtendedButton> backButton( |
| 169 [[BookmarkExtendedButton alloc] initWithFrame:leftButtonFrame]); |
| 170 self.backButton = backButton; |
| 171 self.backButton.extendedEdges = leftButtonInsets; |
| 172 self.backButton.autoresizingMask = |
| 173 UIViewAutoresizingFlexibleTrailingMargin(); |
| 174 self.backButton.backgroundColor = [UIColor clearColor]; |
| 175 UIImage* backImage = [UIImage imageNamed:@"bookmark_gray_back"]; |
| 176 [self.backButton setBackgroundImage:backImage |
| 177 forState:UIControlStateNormal]; |
| 178 self.backButton.accessibilityLabel = |
| 179 l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_BACK_LABEL); |
| 180 self.backButton.accessibilityIdentifier = @"Parent"; |
| 181 self.backButton.alpha = 0; |
| 182 [self.contentView addSubview:self.backButton]; |
| 183 |
| 184 [self setNeedsLayout]; |
| 185 } |
| 186 return self; |
| 187 } |
| 188 |
| 189 - (void)layoutSubviews { |
| 190 [super layoutSubviews]; |
| 191 |
| 192 // When the alpha of the button is less than this amount, the title is |
| 193 // allowed to overrun the button. Generally, layoutSubviews should only be |
| 194 // called with buttons having an alpha of 0.0 or 1.0, so the value of this |
| 195 // constant doesn't matter too much. |
| 196 const CGFloat buttonAlphaForTitleOverrun = 0.1; |
| 197 |
| 198 LayoutOffset labelTrailing = 0; |
| 199 |
| 200 // The title should not overrun the cancel or edit buttons. |
| 201 if (self.editButton && self.editButton.alpha > buttonAlphaForTitleOverrun) { |
| 202 labelTrailing = CGRectGetTrailingLayoutOffsetInBoundingRect( |
| 203 self.editButton.frame, self.contentView.bounds) + |
| 204 CGRectGetWidth(self.editButton.frame) + kInterButtonMargin; |
| 205 } else if (self.cancelButton) { |
| 206 labelTrailing = CGRectGetTrailingLayoutOffsetInBoundingRect( |
| 207 self.cancelButton.frame, self.contentView.bounds) + |
| 208 CGRectGetWidth(self.cancelButton.frame) + |
| 209 kInterButtonMargin; |
| 210 } |
| 211 |
| 212 CGRect leadingRect = self.menuButton.frame; |
| 213 if (!bookmark_utils_ios::bookmarkMenuIsInSlideInPanel() && |
| 214 self.backButton.alpha < buttonAlphaForTitleOverrun) { |
| 215 leadingRect = self.backButton.frame; |
| 216 } |
| 217 |
| 218 LayoutOffset labelLeading = CGRectGetLeadingLayoutOffsetInBoundingRect( |
| 219 leadingRect, self.contentView.bounds) + |
| 220 CGRectGetWidth(leadingRect) + kInterButtonMargin; |
| 221 |
| 222 CGFloat width = |
| 223 CGRectGetWidth(self.contentView.bounds) - (labelTrailing + labelLeading); |
| 224 |
| 225 self.titleLabel.frame = LayoutRectGetRect( |
| 226 LayoutRectMake(labelLeading, CGRectGetWidth(self.contentView.bounds), 0, |
| 227 width, CGRectGetHeight(self.contentView.bounds))); |
| 228 |
| 229 if (bookmark_utils_ios::bookmarkMenuIsInSlideInPanel()) |
| 230 self.menuButton.hidden = NO; |
| 231 else |
| 232 self.menuButton.hidden = YES; |
| 233 } |
| 234 |
| 235 + (CGFloat)expectedContentViewHeight { |
| 236 return kContentHeight; |
| 237 } |
| 238 |
| 239 - (void)setCancelTarget:(id)target action:(SEL)action { |
| 240 [self.cancelButton addTarget:target |
| 241 action:action |
| 242 forControlEvents:UIControlEventTouchUpInside]; |
| 243 DCHECK(!IsIPadIdiom()); |
| 244 } |
| 245 |
| 246 - (void)setEditTarget:(id)target action:(SEL)action { |
| 247 [self.editButton addTarget:target |
| 248 action:action |
| 249 forControlEvents:UIControlEventTouchUpInside]; |
| 250 } |
| 251 |
| 252 - (void)setMenuTarget:(id)target action:(SEL)action { |
| 253 [self.menuButton addTarget:target |
| 254 action:action |
| 255 forControlEvents:UIControlEventTouchUpInside]; |
| 256 } |
| 257 |
| 258 - (void)setBackTarget:(id)target action:(SEL)action { |
| 259 [self.backButton addTarget:target |
| 260 action:action |
| 261 forControlEvents:UIControlEventTouchUpInside]; |
| 262 } |
| 263 |
| 264 - (void)setTitle:(NSString*)title { |
| 265 self.titleLabel.text = title; |
| 266 [self setNeedsLayout]; |
| 267 } |
| 268 |
| 269 - (void)showEditButtonWithAnimationDuration:(CGFloat)duration { |
| 270 if (self.editButton.alpha == 1.0) |
| 271 return; |
| 272 if (duration == 0.0) { |
| 273 self.editButton.alpha = 1.0; |
| 274 [self setNeedsLayout]; |
| 275 return; |
| 276 } |
| 277 [UIView animateWithDuration:duration |
| 278 delay:0 |
| 279 options:UIViewAnimationOptionBeginFromCurrentState |
| 280 animations:^{ |
| 281 self.editButton.alpha = 1.0; |
| 282 } |
| 283 completion:^(BOOL finished) { |
| 284 if (finished) |
| 285 [self setNeedsLayout]; |
| 286 }]; |
| 287 } |
| 288 |
| 289 - (void)hideEditButtonWithAnimationDuration:(CGFloat)duration { |
| 290 if (self.editButton.alpha == 0.0) |
| 291 return; |
| 292 if (duration == 0.0) { |
| 293 self.editButton.alpha = 0.0; |
| 294 [self setNeedsLayout]; |
| 295 return; |
| 296 } |
| 297 [UIView animateWithDuration:duration |
| 298 delay:0 |
| 299 options:UIViewAnimationOptionBeginFromCurrentState |
| 300 animations:^{ |
| 301 self.editButton.alpha = 0.0; |
| 302 } |
| 303 completion:^(BOOL finished) { |
| 304 if (finished) { |
| 305 [self setNeedsLayout]; |
| 306 } |
| 307 }]; |
| 308 } |
| 309 |
| 310 - (void)updateEditButtonVisibility:(CGFloat)visibility { |
| 311 self.editButton.alpha = visibility; |
| 312 } |
| 313 |
| 314 - (void)showMenuButtonInsteadOfBackButton:(CGFloat)duration { |
| 315 if (self.menuButton.alpha == 1.0 && self.backButton.alpha == 0.0) |
| 316 return; |
| 317 if (duration == 0.0) { |
| 318 self.menuButton.alpha = 1.0; |
| 319 self.backButton.alpha = 0.0; |
| 320 [self setNeedsLayout]; |
| 321 return; |
| 322 } |
| 323 [UIView animateWithDuration:duration |
| 324 delay:0 |
| 325 options:UIViewAnimationOptionBeginFromCurrentState |
| 326 animations:^{ |
| 327 self.menuButton.alpha = 1.0; |
| 328 self.backButton.alpha = 0.0; |
| 329 } |
| 330 completion:^(BOOL finished) { |
| 331 if (finished) { |
| 332 [self setNeedsLayout]; |
| 333 } |
| 334 }]; |
| 335 } |
| 336 |
| 337 - (void)showBackButtonInsteadOfMenuButton:(CGFloat)duration { |
| 338 if (self.menuButton.alpha == 0.0 && self.backButton.alpha == 1.0) |
| 339 return; |
| 340 if (duration == 0.0) { |
| 341 self.menuButton.alpha = 0.0; |
| 342 self.backButton.alpha = 1.0; |
| 343 [self setNeedsLayout]; |
| 344 return; |
| 345 } |
| 346 [UIView animateWithDuration:duration |
| 347 delay:0 |
| 348 options:UIViewAnimationOptionBeginFromCurrentState |
| 349 animations:^{ |
| 350 self.menuButton.alpha = 0.0; |
| 351 self.backButton.alpha = 1.0; |
| 352 } |
| 353 completion:^(BOOL finished) { |
| 354 if (finished) { |
| 355 [self setNeedsLayout]; |
| 356 } |
| 357 }]; |
| 358 } |
| 359 |
| 360 @end |
OLD | NEW |