Commit be322fe0 authored by Marti Wong's avatar Marti Wong Committed by Commit Bot

Refine the style of the bottom toolbar in iOS history.

As per UI review request, adjust the style of history ClearBrowsingBar:
1. Horizontal margin: 16pt
2. Vertical margin: 8pt
3. Spacing between button: 8pt
4. Font size: (same as bookmark cell)
5. Font color
6. Shadow opacity and radius
7. Button text wraps across multi-lines when needed (and bar height will
   grow when text wrapped.)

Screenshot:
https://drive.google.com/file/d/1rRj-1fKsjRk8n0rG6C-XB2mXoyPooMC6

Bug: 788601
Change-Id: I9a0fbe68122e01301665a48ed77086be96d7de65
Reviewed-on: https://chromium-review.googlesource.com/790013
Commit-Queue: Marti Wong <martiw@chromium.org>
Reviewed-by: default avatarLouis Romero <lpromero@chromium.org>
Cr-Commit-Position: refs/heads/master@{#519535}
parent 0e25e78e
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
- (void)setDeleteTarget:(id)taret action:(SEL)action; - (void)setDeleteTarget:(id)taret action:(SEL)action;
// Sets the target/action of the "Cancel" button. // Sets the target/action of the "Cancel" button.
- (void)setCancelTarget:(id)target action:(SEL)action; - (void)setCancelTarget:(id)target action:(SEL)action;
// Updates the height of the ClearBrowsingBar.
- (void)updateHeight;
@end @end
#endif // IOS_CHROME_BROWSER_UI_HISTORY_CLEAR_BROWSING_BAR_H_ #endif // IOS_CHROME_BROWSER_UI_HISTORY_CLEAR_BROWSING_BAR_H_
...@@ -6,12 +6,14 @@ ...@@ -6,12 +6,14 @@
#include "base/logging.h" #include "base/logging.h"
#include "components/strings/grit/components_strings.h" #include "components/strings/grit/components_strings.h"
#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
#include "ios/chrome/browser/ui/rtl_geometry.h" #include "ios/chrome/browser/ui/rtl_geometry.h"
#import "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/chrome/browser/ui/uikit_ui_util.h"
#import "ios/chrome/browser/ui/util/constraints_ui_util.h" #import "ios/chrome/browser/ui/util/constraints_ui_util.h"
#import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h" #import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
#include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/l10n/l10n_util_mac.h"
#import "ui/gfx/ios/NSString+CrStringDrawing.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
...@@ -19,11 +21,21 @@ ...@@ -19,11 +21,21 @@
namespace { namespace {
// Shadow opacity for the clear browsing bar. // Shadow opacity for the clear browsing bar.
CGFloat kShadowOpacity = 0.2f; const CGFloat kShadowOpacity = 0.12f;
// Horizontal margin for the contents of ClearBrowsingBar. // Shadow radius for the clear browsing bar.
CGFloat kHorizontalMargin = 8.0f; const CGFloat kShadowRadius = 12.0f;
// Height of the part of the toolbar containing content. // Horizontal margin and spacing for the contents of clear browsing bar.
const CGFloat kToolbarHeight = 48.0f; const CGFloat kHorizontalMargin = 16.0f;
// Vertical margin for the contents of clear browsing bar.
const CGFloat kVerticalMargin = 8.0f;
// Horizontal spacing between the buttons inside clear browsing bar.
const CGFloat kHorizontalSpacing = 8.0f;
// Height of the toolbar in normal state.
const CGFloat kToolbarNormalHeight = 48.0f;
// Height of the expanded toolbar (buttons on multiple lines).
const CGFloat kToolbarExpandedHeight = 58.0f;
// Maximum proportion of the width of a button in the toolbar.
const CGFloat kMaxButtonWidthRatio = 0.52f;
// Enum to specify button position in the clear browsing bar. // Enum to specify button position in the clear browsing bar.
typedef NS_ENUM(BOOL, ButtonPlacement) { Leading, Trailing }; typedef NS_ENUM(BOOL, ButtonPlacement) { Leading, Trailing };
} // namespace } // namespace
...@@ -32,14 +44,20 @@ typedef NS_ENUM(BOOL, ButtonPlacement) { Leading, Trailing }; ...@@ -32,14 +44,20 @@ typedef NS_ENUM(BOOL, ButtonPlacement) { Leading, Trailing };
// Button that displays "Clear Browsing Data...". // Button that displays "Clear Browsing Data...".
@property(nonatomic, strong) UIButton* clearBrowsingDataButton; @property(nonatomic, strong) UIButton* clearBrowsingDataButton;
@property(nonatomic, strong) UIView* clearButtonContainer;
// Button that displays "Edit". // Button that displays "Edit".
@property(nonatomic, strong) UIButton* editButton; @property(nonatomic, strong) UIButton* editButton;
@property(nonatomic, strong) UIView* editButtonContainer;
// Button that displays "Delete". // Button that displays "Delete".
@property(nonatomic, strong) UIButton* deleteButton; @property(nonatomic, strong) UIButton* deleteButton;
@property(nonatomic, strong) UIView* deleteButtonContainer;
// Button that displays "Cancel". // Button that displays "Cancel".
@property(nonatomic, strong) UIButton* cancelButton; @property(nonatomic, strong) UIButton* cancelButton;
@property(nonatomic, strong) UIView* cancelButtonContainer;
// Stack view for arranging the buttons. // Stack view for arranging the buttons.
@property(nonatomic, strong) UIStackView* stackView; @property(nonatomic, strong) UIStackView* stackView;
// Height constraint for the stack view containing the buttons.
@property(nonatomic, strong) NSLayoutConstraint* heightConstraint;
// Styles button for Leading or Trailing placement. Leading buttons have red // Styles button for Leading or Trailing placement. Leading buttons have red
// text that is aligned to the leading edge. Trailing buttons have blue text // text that is aligned to the leading edge. Trailing buttons have blue text
...@@ -52,43 +70,87 @@ typedef NS_ENUM(BOOL, ButtonPlacement) { Leading, Trailing }; ...@@ -52,43 +70,87 @@ typedef NS_ENUM(BOOL, ButtonPlacement) { Leading, Trailing };
@synthesize editing = _editing; @synthesize editing = _editing;
@synthesize clearBrowsingDataButton = _clearBrowsingDataButton; @synthesize clearBrowsingDataButton = _clearBrowsingDataButton;
@synthesize clearButtonContainer = _clearButtonContainer;
@synthesize editButton = _editButton; @synthesize editButton = _editButton;
@synthesize editButtonContainer = _editButtonContainer;
@synthesize deleteButton = _deleteButton; @synthesize deleteButton = _deleteButton;
@synthesize deleteButtonContainer = _deleteButtonContainer;
@synthesize cancelButton = _cancelButton; @synthesize cancelButton = _cancelButton;
@synthesize cancelButtonContainer = _cancelButtonContainer;
@synthesize stackView = _stackView; @synthesize stackView = _stackView;
@synthesize heightConstraint = _heightConstraint;
- (instancetype)initWithFrame:(CGRect)frame { - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame]; self = [super initWithFrame:frame];
if (self) { if (self) {
NSDictionary* views = nil;
NSArray* constraints = nil;
_clearBrowsingDataButton = [UIButton buttonWithType:UIButtonTypeCustom]; _clearBrowsingDataButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_clearBrowsingDataButton [_clearBrowsingDataButton
setTitle:l10n_util::GetNSStringWithFixup( setTitle:l10n_util::GetNSStringWithFixup(
IDS_HISTORY_OPEN_CLEAR_BROWSING_DATA_DIALOG) IDS_HISTORY_OPEN_CLEAR_BROWSING_DATA_DIALOG)
forState:UIControlStateNormal]; forState:UIControlStateNormal];
[self styleButton:_clearBrowsingDataButton forPlacement:Leading]; [self styleButton:_clearBrowsingDataButton forPlacement:Leading];
_clearButtonContainer = [[UIView alloc] init];
[_clearButtonContainer addSubview:_clearBrowsingDataButton];
views = @{@"button" : _clearBrowsingDataButton};
constraints = @[ @"V:|[button]|", @"H:|[button]" ];
ApplyVisualConstraints(constraints, views);
[_clearBrowsingDataButton.trailingAnchor
constraintLessThanOrEqualToAnchor:_clearButtonContainer.trailingAnchor]
.active = YES;
_editButton = [UIButton buttonWithType:UIButtonTypeCustom]; _editButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_editButton [_editButton
setTitle:l10n_util::GetNSString(IDS_HISTORY_START_EDITING_BUTTON) setTitle:l10n_util::GetNSString(IDS_HISTORY_START_EDITING_BUTTON)
forState:UIControlStateNormal]; forState:UIControlStateNormal];
[self styleButton:_editButton forPlacement:Trailing]; [self styleButton:_editButton forPlacement:Trailing];
_editButtonContainer = [[UIView alloc] init];
[_editButtonContainer addSubview:_editButton];
views = @{@"button" : _editButton};
constraints = @[ @"V:|[button]|", @"H:[button]|" ];
ApplyVisualConstraints(constraints, views);
[_editButton.leadingAnchor
constraintGreaterThanOrEqualToAnchor:_editButtonContainer.leadingAnchor]
.active = YES;
_deleteButton = [UIButton buttonWithType:UIButtonTypeCustom]; _deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_deleteButton setTitle:l10n_util::GetNSString( [_deleteButton setTitle:l10n_util::GetNSString(
IDS_HISTORY_DELETE_SELECTED_ENTRIES_BUTTON) IDS_HISTORY_DELETE_SELECTED_ENTRIES_BUTTON)
forState:UIControlStateNormal]; forState:UIControlStateNormal];
[self styleButton:_deleteButton forPlacement:Leading]; [self styleButton:_deleteButton forPlacement:Leading];
_deleteButtonContainer = [[UIView alloc] init];
[_deleteButtonContainer addSubview:_deleteButton];
views = @{@"button" : _deleteButton};
constraints = @[ @"V:|[button]|", @"H:|[button]" ];
ApplyVisualConstraints(constraints, views);
[_deleteButton.trailingAnchor
constraintLessThanOrEqualToAnchor:_deleteButtonContainer.trailingAnchor]
.active = YES;
_cancelButton = [UIButton buttonWithType:UIButtonTypeCustom]; _cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_cancelButton [_cancelButton
setTitle:l10n_util::GetNSString(IDS_HISTORY_CANCEL_EDITING_BUTTON) setTitle:l10n_util::GetNSString(IDS_HISTORY_CANCEL_EDITING_BUTTON)
forState:UIControlStateNormal]; forState:UIControlStateNormal];
[self styleButton:_cancelButton forPlacement:Trailing]; [self styleButton:_cancelButton forPlacement:Trailing];
_cancelButtonContainer = [[UIView alloc] init];
[_cancelButtonContainer addSubview:_cancelButton];
views = @{@"button" : _cancelButton};
constraints = @[ @"V:|[button]|", @"H:[button]|" ];
ApplyVisualConstraints(constraints, views);
[_cancelButton.leadingAnchor
constraintGreaterThanOrEqualToAnchor:_cancelButtonContainer
.leadingAnchor]
.active = YES;
_stackView = [[UIStackView alloc] initWithArrangedSubviews:@[ _stackView = [[UIStackView alloc] initWithArrangedSubviews:@[
_clearBrowsingDataButton, _editButton, _deleteButton, _cancelButton _clearButtonContainer, _editButtonContainer, _deleteButtonContainer,
_cancelButtonContainer
]]; ]];
_stackView.alignment = UIStackViewAlignmentFill; _stackView.alignment = UIStackViewAlignmentCenter;
_stackView.distribution = UIStackViewDistributionEqualSpacing; _stackView.distribution = UIStackViewDistributionEqualSpacing;
_stackView.axis = UILayoutConstraintAxisHorizontal; _stackView.axis = UILayoutConstraintAxisHorizontal;
...@@ -96,15 +158,26 @@ typedef NS_ENUM(BOOL, ButtonPlacement) { Leading, Trailing }; ...@@ -96,15 +158,26 @@ typedef NS_ENUM(BOOL, ButtonPlacement) { Leading, Trailing };
_stackView.translatesAutoresizingMaskIntoConstraints = NO; _stackView.translatesAutoresizingMaskIntoConstraints = NO;
PinToSafeArea(_stackView, self); PinToSafeArea(_stackView, self);
[_stackView.heightAnchor constraintEqualToConstant:kToolbarHeight].active = _heightConstraint = [_stackView.heightAnchor
YES; constraintEqualToConstant:kToolbarNormalHeight];
_heightConstraint.active = YES;
_stackView.layoutMarginsRelativeArrangement = YES; _stackView.layoutMarginsRelativeArrangement = YES;
_stackView.layoutMargins = _stackView.layoutMargins = UIEdgeInsetsMake(
UIEdgeInsetsMake(0, kHorizontalMargin, 0, kHorizontalMargin); kVerticalMargin, kHorizontalMargin, kVerticalMargin, kHorizontalMargin);
_stackView.spacing = kHorizontalSpacing;
for (UIButton* button in @[
_clearBrowsingDataButton, _editButton, _deleteButton, _cancelButton
]) {
[button.widthAnchor
constraintLessThanOrEqualToAnchor:_stackView.widthAnchor
multiplier:kMaxButtonWidthRatio]
.active = YES;
}
[self setBackgroundColor:[UIColor whiteColor]]; [self setBackgroundColor:[UIColor whiteColor]];
[[self layer] setShadowOpacity:kShadowOpacity]; [[self layer] setShadowOpacity:kShadowOpacity];
[[self layer] setShadowRadius:kShadowRadius];
[self setEditing:NO]; [self setEditing:NO];
} }
return self; return self;
...@@ -114,10 +187,12 @@ typedef NS_ENUM(BOOL, ButtonPlacement) { Leading, Trailing }; ...@@ -114,10 +187,12 @@ typedef NS_ENUM(BOOL, ButtonPlacement) { Leading, Trailing };
- (void)setEditing:(BOOL)editing { - (void)setEditing:(BOOL)editing {
_editing = editing; _editing = editing;
self.clearBrowsingDataButton.hidden = editing; self.clearButtonContainer.hidden = editing;
self.editButton.hidden = editing; self.editButtonContainer.hidden = editing;
self.deleteButton.hidden = !editing; self.deleteButtonContainer.hidden = !editing;
self.cancelButton.hidden = !editing; self.cancelButtonContainer.hidden = !editing;
[self updateHeight];
} }
- (BOOL)isEditButtonEnabled { - (BOOL)isEditButtonEnabled {
...@@ -160,22 +235,63 @@ typedef NS_ENUM(BOOL, ButtonPlacement) { Leading, Trailing }; ...@@ -160,22 +235,63 @@ typedef NS_ENUM(BOOL, ButtonPlacement) { Leading, Trailing };
forControlEvents:UIControlEventTouchUpInside]; forControlEvents:UIControlEventTouchUpInside];
} }
- (void)updateHeight {
NSArray* buttons =
@[ _clearBrowsingDataButton, _editButton, _deleteButton, _cancelButton ];
CGFloat buttonMaxWidth = self.frame.size.width * kMaxButtonWidthRatio;
CGFloat availableWidth = self.frame.size.width - kHorizontalMargin * 2;
NSUInteger visibleCount = 0;
// Count the number of visible buttons and deduct the button spacings from
// availableWidth.
for (UIButton* button in buttons) {
if (!button.superview.hidden) {
visibleCount++;
if (visibleCount > 1) {
availableWidth -= kHorizontalSpacing;
}
}
}
// Expand toolbar height in case word wrapping happens.
for (UIButton* button in buttons) {
if (!button.superview.hidden) {
CGFloat rect = [button.titleLabel.text
cr_pixelAlignedSizeWithFont:button.titleLabel.font]
.width;
if (rect > availableWidth || rect > buttonMaxWidth) {
self.heightConstraint.constant = kToolbarExpandedHeight;
return;
}
availableWidth -= rect;
}
}
// Use the normal height when there is no word wrapping.
self.heightConstraint.constant = kToolbarNormalHeight;
}
#pragma mark Private Methods #pragma mark Private Methods
- (void)styleButton:(UIButton*)button forPlacement:(ButtonPlacement)placement { - (void)styleButton:(UIButton*)button forPlacement:(ButtonPlacement)placement {
BOOL leading = placement == Leading; BOOL leading = placement == Leading;
BOOL alignmentLeft = leading ^ UseRTLLayout();
[button setBackgroundColor:[UIColor whiteColor]]; [button setBackgroundColor:[UIColor whiteColor]];
UIColor* textColor = leading ? [[MDCPalette redPalette] tint500] UIColor* textColor = leading ? [[MDCPalette cr_redPalette] tint500]
: [[MDCPalette bluePalette] tint500]; : [[MDCPalette cr_bluePalette] tint500];
[button setTitleColor:textColor forState:UIControlStateNormal]; [button setTitleColor:textColor forState:UIControlStateNormal];
[button setTitleColor:[[MDCPalette greyPalette] tint500] [button setTitleColor:[[MDCPalette greyPalette] tint500]
forState:UIControlStateDisabled]; forState:UIControlStateDisabled];
[[button titleLabel] [[button titleLabel] setFont:[MDCTypography subheadFont]];
setFont:[[MDCTypography fontLoader] regularFontOfSize:14]]; button.titleLabel.textAlignment =
alignmentLeft ? NSTextAlignmentLeft : NSTextAlignmentRight;
button.contentHorizontalAlignment = button.contentHorizontalAlignment =
leading ^ UseRTLLayout() ? UIControlContentHorizontalAlignmentLeft alignmentLeft ? UIControlContentHorizontalAlignmentLeft
: UIControlContentHorizontalAlignmentRight; : UIControlContentHorizontalAlignmentRight;
[button setTranslatesAutoresizingMaskIntoConstraints:NO]; [button setTranslatesAutoresizingMaskIntoConstraints:NO];
button.titleLabel.numberOfLines = 2;
button.titleLabel.adjustsFontSizeToFitWidth = YES;
} }
@end @end
...@@ -188,6 +188,11 @@ CGFloat kShadowOpacity = 0.2f; ...@@ -188,6 +188,11 @@ CGFloat kShadowOpacity = 0.2f;
return NO; return NO;
} }
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)orient {
[super didRotateFromInterfaceOrientation:orient];
[_clearBrowsingBar updateHeight];
}
#pragma mark - Status bar #pragma mark - Status bar
- (BOOL)modalPresentationCapturesStatusBarAppearance { - (BOOL)modalPresentationCapturesStatusBarAppearance {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment