Commit 21f85b49 authored by edchin's avatar edchin Committed by Commit Bot

[ios] Refactor tab grid toolbars and buttons configuration

The configuration of the toolbars and buttons has gotten
unwieldy so this CL attempts to simplify the code.

This CL also adds assets for the new tab button.

Bug: 818198
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: I705ac71ac0c09bc2fea613247a2c043e5cd7ac39
Reviewed-on: https://chromium-review.googlesource.com/961662
Commit-Queue: edchin <edchin@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Reviewed-by: default avataredchin <edchin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543115}
parent b0d842c1
...@@ -68,7 +68,8 @@ source_set("tab_grid_ui") { ...@@ -68,7 +68,8 @@ source_set("tab_grid_ui") {
deps = [ deps = [
"resources:grid_close_cell", "resources:grid_close_cell",
"resources:tab_grid_new_tab_fab", "resources:new_tab_floating_button",
"resources:new_tab_floating_button_incognito",
"//base", "//base",
"//ios/chrome/app/strings", "//ios/chrome/app/strings",
"//ios/chrome/browser", "//ios/chrome/browser",
......
...@@ -13,11 +13,20 @@ imageset("grid_close_cell") { ...@@ -13,11 +13,20 @@ imageset("grid_close_cell") {
] ]
} }
imageset("tab_grid_new_tab_fab") { imageset("new_tab_floating_button") {
sources = [ sources = [
"tab_grid_new_tab_fab.imageset/Contents.json", "new_tab_floating_button.imageset/Contents.json",
"tab_grid_new_tab_fab.imageset/tab_grid_new_tab_fab.png", "new_tab_floating_button.imageset/new_tab_floating_button.png",
"tab_grid_new_tab_fab.imageset/tab_grid_new_tab_fab@2x.png", "new_tab_floating_button.imageset/new_tab_floating_button@2x.png",
"tab_grid_new_tab_fab.imageset/tab_grid_new_tab_fab@3x.png", "new_tab_floating_button.imageset/new_tab_floating_button@3x.png",
]
}
imageset("new_tab_floating_button_incognito") {
sources = [
"new_tab_floating_button_incognito.imageset/Contents.json",
"new_tab_floating_button_incognito.imageset/new_tab_floating_button_incognito.png",
"new_tab_floating_button_incognito.imageset/new_tab_floating_button_incognito@2x.png",
"new_tab_floating_button_incognito.imageset/new_tab_floating_button_incognito@3x.png",
] ]
} }
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
{ {
"idiom": "universal", "idiom": "universal",
"scale": "1x", "scale": "1x",
"filename": "tab_grid_new_tab_fab.png" "filename": "new_tab_floating_button.png"
}, },
{ {
"idiom": "universal", "idiom": "universal",
"scale": "2x", "scale": "2x",
"filename": "tab_grid_new_tab_fab@2x.png" "filename": "new_tab_floating_button@2x.png"
}, },
{ {
"idiom": "universal", "idiom": "universal",
"scale": "3x", "scale": "3x",
"filename": "tab_grid_new_tab_fab@3x.png" "filename": "new_tab_floating_button@3x.png"
} }
], ],
"info": { "info": {
......
{
"images": [
{
"idiom": "universal",
"scale": "1x",
"filename": "new_tab_floating_button_incognito.png"
},
{
"idiom": "universal",
"scale": "2x",
"filename": "new_tab_floating_button_incognito@2x.png"
},
{
"idiom": "universal",
"scale": "3x",
"filename": "new_tab_floating_button_incognito@3x.png"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}
...@@ -20,6 +20,14 @@ ...@@ -20,6 +20,14 @@
NSString* const kTabGridDoneButtonAccessibilityID = NSString* const kTabGridDoneButtonAccessibilityID =
@"TabGridDoneButtonAccessibilityID"; @"TabGridDoneButtonAccessibilityID";
namespace {
// Types of configurations of this view controller.
typedef NS_ENUM(NSUInteger, TabGridConfiguration) {
TabGridConfigurationBottomToolbar = 1,
TabGridConfigurationFloatingButton,
};
} // namespace
@interface TabGridViewController ()<GridViewControllerDelegate, @interface TabGridViewController ()<GridViewControllerDelegate,
UIScrollViewAccessibilityDelegate> UIScrollViewAccessibilityDelegate>
// Child view controllers. // Child view controllers.
...@@ -33,8 +41,14 @@ NSString* const kTabGridDoneButtonAccessibilityID = ...@@ -33,8 +41,14 @@ NSString* const kTabGridDoneButtonAccessibilityID =
@property(nonatomic, weak) TabGridBottomToolbar* bottomToolbar; @property(nonatomic, weak) TabGridBottomToolbar* bottomToolbar;
@property(nonatomic, weak) UIButton* closeAllButton; @property(nonatomic, weak) UIButton* closeAllButton;
@property(nonatomic, weak) UIButton* doneButton; @property(nonatomic, weak) UIButton* doneButton;
@property(nonatomic, weak) UIButton* createTabButton; // Clang does not allow property getters to start with the reserved word "new",
// but provides a workaround. The getter must be set before the property is
// declared.
- (UIButton*)newTabButton __attribute__((objc_method_family(none)));
@property(nonatomic, weak) UIButton* newTabButton;
@property(nonatomic, weak) UIButton* floatingButton; @property(nonatomic, weak) UIButton* floatingButton;
@property(nonatomic, assign) TabGridConfiguration configuration;
@end @end
@implementation TabGridViewController @implementation TabGridViewController
...@@ -56,8 +70,9 @@ NSString* const kTabGridDoneButtonAccessibilityID = ...@@ -56,8 +70,9 @@ NSString* const kTabGridDoneButtonAccessibilityID =
@synthesize bottomToolbar = _bottomToolbar; @synthesize bottomToolbar = _bottomToolbar;
@synthesize closeAllButton = _closeAllButton; @synthesize closeAllButton = _closeAllButton;
@synthesize doneButton = _doneButton; @synthesize doneButton = _doneButton;
@synthesize createTabButton = _createTabButton; @synthesize newTabButton = _newTabButton;
@synthesize floatingButton = _floatingButton; @synthesize floatingButton = _floatingButton;
@synthesize configuration = _configuration;
- (instancetype)init { - (instancetype)init {
if (self = [super init]) { if (self = [super init]) {
...@@ -85,8 +100,7 @@ NSString* const kTabGridDoneButtonAccessibilityID = ...@@ -85,8 +100,7 @@ NSString* const kTabGridDoneButtonAccessibilityID =
// Call the current page setter to sync the scroll view offset to the current // Call the current page setter to sync the scroll view offset to the current
// page value. // page value.
self.currentPage = _currentPage; self.currentPage = _currentPage;
[self updateToolbarsForCurrentSizeClass]; [self configureViewControllerForCurrentSizeClassesAndPage];
[self enableButtonsForCurrentPage];
if (animated && self.transitionCoordinator) { if (animated && self.transitionCoordinator) {
[self animateToolbarsForAppearance]; [self animateToolbarsForAppearance];
} }
...@@ -126,7 +140,7 @@ NSString* const kTabGridDoneButtonAccessibilityID = ...@@ -126,7 +140,7 @@ NSString* const kTabGridDoneButtonAccessibilityID =
float fractionalPage = scrollView.contentOffset.x / pageWidth; float fractionalPage = scrollView.contentOffset.x / pageWidth;
NSUInteger page = lround(fractionalPage); NSUInteger page = lround(fractionalPage);
_currentPage = static_cast<TabGridPage>(page); _currentPage = static_cast<TabGridPage>(page);
[self enableButtonsForCurrentPage]; [self configureButtonsForCurrentPage];
} }
#pragma mark - UIScrollViewAccessibilityDelegate #pragma mark - UIScrollViewAccessibilityDelegate
...@@ -452,10 +466,6 @@ NSString* const kTabGridDoneButtonAccessibilityID = ...@@ -452,10 +466,6 @@ NSString* const kTabGridDoneButtonAccessibilityID =
- (void)setupFloatingButton { - (void)setupFloatingButton {
UIButton* button = [UIButton buttonWithType:UIButtonTypeSystem]; UIButton* button = [UIButton buttonWithType:UIButtonTypeSystem];
button.translatesAutoresizingMaskIntoConstraints = NO; button.translatesAutoresizingMaskIntoConstraints = NO;
[button
setImage:[[UIImage imageNamed:@"tab_grid_new_tab_fab"]
imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
forState:UIControlStateNormal];
[self.view addSubview:button]; [self.view addSubview:button];
self.floatingButton = button; self.floatingButton = button;
NSArray* constraints = @[ NSArray* constraints = @[
...@@ -467,35 +477,47 @@ NSString* const kTabGridDoneButtonAccessibilityID = ...@@ -467,35 +477,47 @@ NSString* const kTabGridDoneButtonAccessibilityID =
[NSLayoutConstraint activateConstraints:constraints]; [NSLayoutConstraint activateConstraints:constraints];
} }
// Sets visibility of toolbars and floating button in the arrangement containing - (void)configureViewControllerForCurrentSizeClassesAndPage {
// the floating button. Also updates |self.doneButton|, |self.closeAllButton|, self.configuration = TabGridConfigurationFloatingButton;
// and |self.createTabButton| to the visible button. if (self.traitCollection.verticalSizeClass ==
- (void)configureToolbarsWithFloatingButton { UIUserInterfaceSizeClassRegular &&
self.topToolbar.leadingButton.hidden = NO; self.traitCollection.horizontalSizeClass ==
self.topToolbar.trailingButton.hidden = NO; UIUserInterfaceSizeClassCompact) {
self.bottomToolbar.hidden = YES; // The only bottom toolbar configuration is when the UI is narrow but
self.floatingButton.hidden = NO; // vertically long.
self.doneButton = self.topToolbar.leadingButton; self.configuration = TabGridConfigurationBottomToolbar;
self.closeAllButton = self.topToolbar.trailingButton; }
self.createTabButton = self.floatingButton; switch (self.configuration) {
} case TabGridConfigurationBottomToolbar:
// Sets visibility of toolbars and floating button in the arrangement that
// includes the bottom toolbar. Also updates |self.doneButton|,
// |self.closeAllButton|, and |self.createTabButton| to the visible button.
- (void)configureToolbarsWithBottomToolbar {
self.topToolbar.leadingButton.hidden = YES; self.topToolbar.leadingButton.hidden = YES;
self.topToolbar.trailingButton.hidden = YES; self.topToolbar.trailingButton.hidden = YES;
self.bottomToolbar.hidden = NO; self.bottomToolbar.hidden = NO;
self.floatingButton.hidden = YES; self.floatingButton.hidden = YES;
self.doneButton = self.bottomToolbar.leadingButton; self.doneButton = self.bottomToolbar.leadingButton;
self.closeAllButton = self.bottomToolbar.trailingButton; self.closeAllButton = self.bottomToolbar.trailingButton;
self.createTabButton = self.bottomToolbar.roundButton; self.newTabButton = self.bottomToolbar.roundButton;
} break;
case TabGridConfigurationFloatingButton:
// Call this method whenever |self.doneButton|, |self.closeAllButton|, or self.topToolbar.leadingButton.hidden = NO;
// |self.createTabButton| is updated. self.topToolbar.trailingButton.hidden = NO;
- (void)resetButtonLabelsAndActions { self.bottomToolbar.hidden = YES;
self.floatingButton.hidden = NO;
self.doneButton = self.topToolbar.leadingButton;
self.closeAllButton = self.topToolbar.trailingButton;
self.newTabButton = self.floatingButton;
break;
}
if (self.traitCollection.verticalSizeClass ==
UIUserInterfaceSizeClassRegular &&
self.traitCollection.horizontalSizeClass ==
UIUserInterfaceSizeClassRegular) {
// There is enough space for the tab view to have a tab strip,
// so put the done button on the trailing side where the tab
// switcher button is located on the tab view. This puts the buttons for
// entering and leaving the tab grid on the same corner.
self.doneButton = self.topToolbar.trailingButton;
self.closeAllButton = self.topToolbar.leadingButton;
}
// TODO(crbug.com/818699) : Localize strings. // TODO(crbug.com/818699) : Localize strings.
[self.doneButton setTitle:@"Done" forState:UIControlStateNormal]; [self.doneButton setTitle:@"Done" forState:UIControlStateNormal];
[self.closeAllButton setTitle:@"Close All" forState:UIControlStateNormal]; [self.closeAllButton setTitle:@"Close All" forState:UIControlStateNormal];
...@@ -506,44 +528,13 @@ NSString* const kTabGridDoneButtonAccessibilityID = ...@@ -506,44 +528,13 @@ NSString* const kTabGridDoneButtonAccessibilityID =
[self.closeAllButton addTarget:self [self.closeAllButton addTarget:self
action:@selector(closeAllButtonTapped:) action:@selector(closeAllButtonTapped:)
forControlEvents:UIControlEventTouchUpInside]; forControlEvents:UIControlEventTouchUpInside];
[self.createTabButton addTarget:self [self.newTabButton addTarget:self
action:@selector(createTabButtonTapped:) action:@selector(newTabButtonTapped:)
forControlEvents:UIControlEventTouchUpInside]; forControlEvents:UIControlEventTouchUpInside];
[self configureButtonsForCurrentPage];
} }
// Sets up the toolbars and buttons based on size class. - (void)configureButtonsForCurrentPage {
- (void)updateToolbarsForCurrentSizeClass {
if (self.traitCollection.verticalSizeClass ==
UIUserInterfaceSizeClassCompact) {
// When the vertical size is limited, we don't want a bottom toolbar.
[self configureToolbarsWithFloatingButton];
[self resetButtonLabelsAndActions];
return;
}
switch (self.traitCollection.horizontalSizeClass) {
case UIUserInterfaceSizeClassCompact:
// The UI is vertically long and narrow so include a bottom toolbar.
[self configureToolbarsWithBottomToolbar];
[self resetButtonLabelsAndActions];
break;
case UIUserInterfaceSizeClassRegular:
// The UI is wide and long and looks best with a FAB.
[self configureToolbarsWithFloatingButton];
// There is enough space for the tab view to have a tab strip,
// so put the done button on the trailing side where the tab
// switcher button is located on the tab view.
self.doneButton = self.topToolbar.trailingButton;
self.closeAllButton = self.topToolbar.leadingButton;
[self resetButtonLabelsAndActions];
break;
case UIUserInterfaceSizeClassUnspecified:
NOTREACHED() << "Invalid size class.";
break;
}
}
// Update |enabled| property of the done and close all buttons.
- (void)enableButtonsForCurrentPage {
switch (self.currentPage) { switch (self.currentPage) {
case TabGridPageIncognitoTabs: case TabGridPageIncognitoTabs:
self.doneButton.enabled = !self.incognitoTabsViewController.isGridEmpty; self.doneButton.enabled = !self.incognitoTabsViewController.isGridEmpty;
...@@ -558,6 +549,51 @@ NSString* const kTabGridDoneButtonAccessibilityID = ...@@ -558,6 +549,51 @@ NSString* const kTabGridDoneButtonAccessibilityID =
self.closeAllButton.enabled = NO; self.closeAllButton.enabled = NO;
break; break;
} }
switch (self.configuration) {
case TabGridConfigurationBottomToolbar:
// TODO(crbug.com/818198) : Add toolbar new tab assets and modify names
// passed below.
[self
updateNewTabButtonWithIncognitoImageName:
@"new_tab_floating_button_incognito"
regularImageName:@"new_tab_floating_button"];
break;
case TabGridConfigurationFloatingButton:
[self
updateNewTabButtonWithIncognitoImageName:
@"new_tab_floating_button_incognito"
regularImageName:@"new_tab_floating_button"];
break;
}
}
- (void)updateNewTabButtonWithIncognitoImageName:(NSString*)incognitoName
regularImageName:(NSString*)regularName {
switch (self.currentPage) {
case TabGridPageIncognitoTabs:
self.newTabButton.enabled = YES;
[self.newTabButton setImage:[[UIImage imageNamed:incognitoName]
imageWithRenderingMode:
UIImageRenderingModeAlwaysOriginal]
forState:UIControlStateNormal];
break;
case TabGridPageRegularTabs:
self.newTabButton.enabled = YES;
[self.newTabButton setImage:[[UIImage imageNamed:regularName]
imageWithRenderingMode:
UIImageRenderingModeAlwaysOriginal]
forState:UIControlStateNormal];
break;
case TabGridPageRemoteTabs:
self.newTabButton.enabled = NO;
// The incognito new tab button image was made so that it can be a
// template image. A template image becomes greyed out when disabled.
[self.newTabButton setImage:[[UIImage imageNamed:incognitoName]
imageWithRenderingMode:
UIImageRenderingModeAlwaysTemplate]
forState:UIControlStateNormal];
break;
}
} }
// Translates the toolbar views offscreen and then animates them back in using // Translates the toolbar views offscreen and then animates them back in using
...@@ -622,12 +658,12 @@ NSString* const kTabGridDoneButtonAccessibilityID = ...@@ -622,12 +658,12 @@ NSString* const kTabGridDoneButtonAccessibilityID =
- (void)lastItemWasClosedInGridViewController: - (void)lastItemWasClosedInGridViewController:
(GridViewController*)gridViewController { (GridViewController*)gridViewController {
[self enableButtonsForCurrentPage]; [self configureButtonsForCurrentPage];
} }
- (void)firstItemWasAddedInGridViewController: - (void)firstItemWasAddedInGridViewController:
(GridViewController*)gridViewController { (GridViewController*)gridViewController {
[self enableButtonsForCurrentPage]; [self configureButtonsForCurrentPage];
} }
#pragma mark - Button actions #pragma mark - Button actions
...@@ -650,7 +686,7 @@ NSString* const kTabGridDoneButtonAccessibilityID = ...@@ -650,7 +686,7 @@ NSString* const kTabGridDoneButtonAccessibilityID =
} }
} }
- (void)createTabButtonTapped:(id)sender { - (void)newTabButtonTapped:(id)sender {
switch (self.currentPage) { switch (self.currentPage) {
case TabGridPageIncognitoTabs: case TabGridPageIncognitoTabs:
[self.incognitoTabsDelegate addNewItem]; [self.incognitoTabsDelegate addNewItem];
......
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