Commit f53bc613 authored by Mark Cogan's avatar Mark Cogan Committed by Commit Bot

[iOS] Page selection control for the tab grid.

This CL creates the custom selection control for the tab grid and
wires it into the TabGridViewController.

There are extensive comments in the TabGridPageSelector class.

Some things to note:

* Labels are used in place of assets for now.

* Dragging the slider in the control isn't possible yet.

* The view controller doesn't yet update the tab counts in the control.

Bug: 804500, 804581
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: If561619091271b7086989f68bb76edb5bd64c16b
Reviewed-on: https://chromium-review.googlesource.com/962791Reviewed-by: default avataredchin <edchin@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Commit-Queue: Mark Cogan <marq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543388}
parent 135538b4
...@@ -53,6 +53,8 @@ source_set("tab_grid_ui") { ...@@ -53,6 +53,8 @@ source_set("tab_grid_ui") {
"grid_view_controller.mm", "grid_view_controller.mm",
"tab_grid_bottom_toolbar.h", "tab_grid_bottom_toolbar.h",
"tab_grid_bottom_toolbar.mm", "tab_grid_bottom_toolbar.mm",
"tab_grid_page_control.h",
"tab_grid_page_control.mm",
"tab_grid_paging.h", "tab_grid_paging.h",
"tab_grid_top_toolbar.h", "tab_grid_top_toolbar.h",
"tab_grid_top_toolbar.mm", "tab_grid_top_toolbar.mm",
......
// Copyright 2018 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_TAB_GRID_TAB_GRID_PAGE_CONTROL_H_
#define IOS_CHROME_BROWSER_UI_TAB_GRID_TAB_GRID_PAGE_CONTROL_H_
#import <UIKit/UIKit.h>
#import "ios/chrome/browser/ui/tab_grid/tab_grid_paging.h"
// A three-sectioned control for selecting a page in the tab grid.
// A "slider" is positioned over the section for the selected page.
// This is a fixed-size control; it's an error to set or change its size.
// The sections are arranged in leading-to-trailing order:
// incognito tabs, regular tabs, remote tabs.
@interface TabGridPageControl : UIControl
// The currently selected page in the control. When this value is changed by
// a user interaction, the UIControlEventValueChanged actions are sent.
// Setting this property will update the position of the slider without
// animation. When an instance of this control is created, this value defaults
// to TabGridPageRegularTabs.
@property(nonatomic, assign) TabGridPage selectedPage;
// The position of the slider, from 0.0 to 1.0, where 0.0 is as far as possible
// to the leading side of the control, and 1.0 is as far as possible to the
// trailing side of the control. Setting this property will update the position
// of the slider without animation. Setting a value below 0.0 or above 1.0 will
// set 0.0 or 1.0 instead.
// Setting this property will *not* update the selected page.
@property(nonatomic, assign) CGFloat sliderPosition;
// Text displayed next to the incognito and inside the regular tabs icons. The
// available space for text is small -- no wider than two numerals. Text wider
// than this will be clipped.
@property(nonatomic, copy) NSString* incognitoText;
@property(nonatomic, copy) NSString* regularText;
// Create and return a new instance of this control. This is the preferred way
// to create instances of this class.
+ (instancetype)pageControl;
// Designated initializer.
- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
// Set |selectedPage| as the selected page. If |animated| is YES, the
// position change of the slider will be animated.
- (void)setSelectedPage:(TabGridPage)selectedPage animated:(BOOL)animated;
@end
#endif // IOS_CHROME_BROWSER_UI_TAB_GRID_TAB_GRID_PAGE_CONTROL_H_
This diff is collapsed.
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
@class TabGridPageControl;
// Toolbar view with two text buttons and a segmented control. The contents have // Toolbar view with two text buttons and a segmented control. The contents have
// a fixed height and are pinned to the bottom of this view, therefore it is // a fixed height and are pinned to the bottom of this view, therefore it is
// intended to be used as a top toolbar. // intended to be used as a top toolbar.
...@@ -15,7 +17,7 @@ ...@@ -15,7 +17,7 @@
// contents, visibility and actions. // contents, visibility and actions.
@property(nonatomic, weak, readonly) UIButton* leadingButton; @property(nonatomic, weak, readonly) UIButton* leadingButton;
@property(nonatomic, weak, readonly) UIButton* trailingButton; @property(nonatomic, weak, readonly) UIButton* trailingButton;
@property(nonatomic, weak, readonly) UIView* segmentedControl; @property(nonatomic, weak, readonly) TabGridPageControl* pageControl;
- (instancetype)init NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; - (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
......
...@@ -4,22 +4,21 @@ ...@@ -4,22 +4,21 @@
#import "ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.h"
#import "ios/chrome/browser/ui/tab_grid/tab_grid_page_control.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."
#endif #endif
namespace { namespace {
// Height of the toolbar. // Height of the toolbar.
const CGFloat kToolbarHeight = 44.0f; const CGFloat kToolbarHeight = 52.0f;
// Height of the segmented control. The segmented control should have an
// intrinsic width.
const CGFloat kSegmentedControlHeight = 30.0f;
} // namespace } // namespace
@implementation TabGridTopToolbar @implementation TabGridTopToolbar
@synthesize leadingButton = _leadingButton; @synthesize leadingButton = _leadingButton;
@synthesize trailingButton = _trailingButton; @synthesize trailingButton = _trailingButton;
@synthesize segmentedControl = _segmentedControl; @synthesize pageControl = _pageControl;
- (instancetype)init { - (instancetype)init {
if (self = [super initWithFrame:CGRectZero]) { if (self = [super initWithFrame:CGRectZero]) {
...@@ -37,12 +36,9 @@ const CGFloat kSegmentedControlHeight = 30.0f; ...@@ -37,12 +36,9 @@ const CGFloat kSegmentedControlHeight = 30.0f;
leadingButton.titleLabel.adjustsFontForContentSizeCategory = YES; leadingButton.titleLabel.adjustsFontForContentSizeCategory = YES;
leadingButton.tintColor = [UIColor whiteColor]; leadingButton.tintColor = [UIColor whiteColor];
UILabel* segmentedControl = [[UILabel alloc] init]; // The segmented control has an intrinsic size.
segmentedControl.translatesAutoresizingMaskIntoConstraints = NO; TabGridPageControl* pageControl = [[TabGridPageControl alloc] init];
segmentedControl.backgroundColor = [UIColor whiteColor]; pageControl.translatesAutoresizingMaskIntoConstraints = NO;
segmentedControl.text = @"Segmented Control";
segmentedControl.layer.cornerRadius = 11.0f;
segmentedControl.layer.masksToBounds = YES;
UIButton* trailingButton = [UIButton buttonWithType:UIButtonTypeSystem]; UIButton* trailingButton = [UIButton buttonWithType:UIButtonTypeSystem];
trailingButton.translatesAutoresizingMaskIntoConstraints = NO; trailingButton.translatesAutoresizingMaskIntoConstraints = NO;
...@@ -53,10 +49,10 @@ const CGFloat kSegmentedControlHeight = 30.0f; ...@@ -53,10 +49,10 @@ const CGFloat kSegmentedControlHeight = 30.0f;
[toolbar.contentView addSubview:leadingButton]; [toolbar.contentView addSubview:leadingButton];
[toolbar.contentView addSubview:trailingButton]; [toolbar.contentView addSubview:trailingButton];
[toolbar.contentView addSubview:segmentedControl]; [toolbar.contentView addSubview:pageControl];
_leadingButton = leadingButton; _leadingButton = leadingButton;
_trailingButton = trailingButton; _trailingButton = trailingButton;
_segmentedControl = segmentedControl; _pageControl = pageControl;
NSArray* constraints = @[ NSArray* constraints = @[
[toolbar.topAnchor constraintEqualToAnchor:self.topAnchor], [toolbar.topAnchor constraintEqualToAnchor:self.topAnchor],
...@@ -67,13 +63,9 @@ const CGFloat kSegmentedControlHeight = 30.0f; ...@@ -67,13 +63,9 @@ const CGFloat kSegmentedControlHeight = 30.0f;
[leadingButton.leadingAnchor [leadingButton.leadingAnchor
constraintEqualToAnchor:toolbar.layoutMarginsGuide.leadingAnchor], constraintEqualToAnchor:toolbar.layoutMarginsGuide.leadingAnchor],
[leadingButton.bottomAnchor constraintEqualToAnchor:toolbar.bottomAnchor], [leadingButton.bottomAnchor constraintEqualToAnchor:toolbar.bottomAnchor],
[segmentedControl.heightAnchor [pageControl.centerXAnchor constraintEqualToAnchor:toolbar.centerXAnchor],
constraintEqualToConstant:kSegmentedControlHeight], [pageControl.bottomAnchor constraintEqualToAnchor:toolbar.bottomAnchor
[segmentedControl.centerXAnchor constant:-7.0f],
constraintEqualToAnchor:toolbar.centerXAnchor],
[segmentedControl.bottomAnchor
constraintEqualToAnchor:toolbar.bottomAnchor
constant:-7.0f],
[trailingButton.heightAnchor constraintEqualToConstant:kToolbarHeight], [trailingButton.heightAnchor constraintEqualToConstant:kToolbarHeight],
[trailingButton.trailingAnchor [trailingButton.trailingAnchor
constraintEqualToAnchor:toolbar.layoutMarginsGuide.trailingAnchor], constraintEqualToAnchor:toolbar.layoutMarginsGuide.trailingAnchor],
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#import "ios/chrome/browser/ui/tab_grid/grid_image_data_source.h" #import "ios/chrome/browser/ui/tab_grid/grid_image_data_source.h"
#import "ios/chrome/browser/ui/tab_grid/grid_view_controller.h" #import "ios/chrome/browser/ui/tab_grid/grid_view_controller.h"
#import "ios/chrome/browser/ui/tab_grid/tab_grid_bottom_toolbar.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_bottom_toolbar.h"
#import "ios/chrome/browser/ui/tab_grid/tab_grid_page_control.h"
#import "ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_top_toolbar.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
...@@ -134,6 +135,15 @@ typedef NS_ENUM(NSUInteger, TabGridConfiguration) { ...@@ -134,6 +135,15 @@ typedef NS_ENUM(NSUInteger, TabGridConfiguration) {
#pragma mark - UIScrollViewDelegate #pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView*)scrollView {
if (scrollView.dragging) {
CGFloat offsetWidth =
self.scrollView.contentSize.width - self.scrollView.frame.size.width;
CGFloat offset = scrollView.contentOffset.x / offsetWidth;
self.topToolbar.pageControl.sliderPosition = offset;
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView { - (void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView {
// Bookkeeping for the current page. // Bookkeeping for the current page.
CGFloat pageWidth = scrollView.frame.size.width; CGFloat pageWidth = scrollView.frame.size.width;
...@@ -526,6 +536,7 @@ typedef NS_ENUM(NSUInteger, TabGridConfiguration) { ...@@ -526,6 +536,7 @@ typedef NS_ENUM(NSUInteger, TabGridConfiguration) {
self.doneButton = self.topToolbar.trailingButton; self.doneButton = self.topToolbar.trailingButton;
self.closeAllButton = self.topToolbar.leadingButton; 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];
...@@ -539,10 +550,17 @@ typedef NS_ENUM(NSUInteger, TabGridConfiguration) { ...@@ -539,10 +550,17 @@ typedef NS_ENUM(NSUInteger, TabGridConfiguration) {
[self.newTabButton addTarget:self [self.newTabButton addTarget:self
action:@selector(newTabButtonTapped:) action:@selector(newTabButtonTapped:)
forControlEvents:UIControlEventTouchUpInside]; forControlEvents:UIControlEventTouchUpInside];
[self.topToolbar.pageControl addTarget:self
action:@selector(pageControlChanged:)
forControlEvents:UIControlEventValueChanged];
// TODO(crbug.com/804501): Use the actual live tab counts.
self.topToolbar.pageControl.regularText = @"5";
self.topToolbar.pageControl.incognitoText = @"0";
[self configureButtonsForCurrentPage]; [self configureButtonsForCurrentPage];
} }
- (void)configureButtonsForCurrentPage { - (void)configureButtonsForCurrentPage {
[self.topToolbar.pageControl setSelectedPage:self.currentPage animated:YES];
switch (self.currentPage) { switch (self.currentPage) {
case TabGridPageIncognitoTabs: case TabGridPageIncognitoTabs:
self.doneButton.enabled = !self.incognitoTabsViewController.isGridEmpty; self.doneButton.enabled = !self.incognitoTabsViewController.isGridEmpty;
...@@ -671,7 +689,7 @@ typedef NS_ENUM(NSUInteger, TabGridConfiguration) { ...@@ -671,7 +689,7 @@ typedef NS_ENUM(NSUInteger, TabGridConfiguration) {
[self configureButtonsForCurrentPage]; [self configureButtonsForCurrentPage];
} }
#pragma mark - Button actions #pragma mark - Control actions
- (void)doneButtonTapped:(id)sender { - (void)doneButtonTapped:(id)sender {
[self.tabPresentationDelegate showActiveTab]; [self.tabPresentationDelegate showActiveTab];
...@@ -707,4 +725,8 @@ typedef NS_ENUM(NSUInteger, TabGridConfiguration) { ...@@ -707,4 +725,8 @@ typedef NS_ENUM(NSUInteger, TabGridConfiguration) {
} }
} }
- (void)pageControlChanged:(id)sender {
self.currentPage = self.topToolbar.pageControl.selectedPage;
}
@end @end
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