OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "ios/clean/chrome/browser/ui/tools/menu_view_controller.h" | 5 #import "ios/clean/chrome/browser/ui/tools/menu_view_controller.h" |
6 | 6 |
7 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
8 #import "base/logging.h" | 8 #import "base/logging.h" |
9 #import "base/mac/foundation_util.h" | 9 #import "base/mac/foundation_util.h" |
10 #import "base/macros.h" | 10 #import "base/macros.h" |
11 #import "ios/chrome/browser/ui/rtl_geometry.h" | 11 #import "ios/chrome/browser/ui/rtl_geometry.h" |
12 #import "ios/clean/chrome/browser/ui/commands/find_in_page_visibility_commands.h
" | 12 #import "ios/clean/chrome/browser/ui/commands/find_in_page_visibility_commands.h
" |
13 #import "ios/clean/chrome/browser/ui/commands/navigation_commands.h" | 13 #import "ios/clean/chrome/browser/ui/commands/navigation_commands.h" |
14 #import "ios/clean/chrome/browser/ui/commands/tools_menu_commands.h" | 14 #import "ios/clean/chrome/browser/ui/commands/tools_menu_commands.h" |
| 15 #import "ios/clean/chrome/browser/ui/toolbar/toolbar_button+factory.h" |
15 #import "ios/clean/chrome/browser/ui/toolbar/toolbar_button.h" | 16 #import "ios/clean/chrome/browser/ui/toolbar/toolbar_button.h" |
16 #import "ios/clean/chrome/browser/ui/tools/menu_overflow_controls_stackview.h" | 17 #import "ios/clean/chrome/browser/ui/tools/menu_overflow_controls_stackview.h" |
17 #import "ios/clean/chrome/browser/ui/tools/tools_actions.h" | 18 #import "ios/clean/chrome/browser/ui/tools/tools_actions.h" |
18 #import "ios/clean/chrome/browser/ui/tools/tools_menu_item.h" | 19 #import "ios/clean/chrome/browser/ui/tools/tools_menu_item.h" |
19 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" | 20 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" |
20 | 21 |
21 #if !defined(__has_feature) || !__has_feature(objc_arc) | 22 #if !defined(__has_feature) || !__has_feature(objc_arc) |
22 #error "This file requires ARC support." | 23 #error "This file requires ARC support." |
23 #endif | 24 #endif |
24 | 25 |
25 namespace { | 26 namespace { |
26 const CGFloat kMenuWidth = 250; | 27 const CGFloat kMenuWidth = 250.0; |
27 const CGFloat kMenuItemHeight = 48; | 28 const CGFloat kMenuItemHeight = 48.0; |
| 29 const CGFloat kMenuItemLeadingEdgeInset = 10.0; |
| 30 const CGFloat kOverflowControlsMargin = 50.0; |
| 31 const CGFloat kCloseButtonHeight = 44.0; |
28 } | 32 } |
29 | 33 |
30 @interface MenuViewController ()<ToolsActions> | 34 @interface MenuViewController ()<ToolsActions> |
| 35 @property(nonatomic, strong) UIScrollView* menuScrollView; |
31 @property(nonatomic, strong) UIStackView* menuStackView; | 36 @property(nonatomic, strong) UIStackView* menuStackView; |
32 @property(nonatomic, strong) NSArray<ToolsMenuItem*>* menuItems; | 37 @property(nonatomic, strong) NSArray<ToolsMenuItem*>* menuItems; |
33 @property(nonatomic, strong) | 38 @property(nonatomic, strong) |
34 MenuOverflowControlsStackView* toolbarOverflowStackView; | 39 MenuOverflowControlsStackView* toolbarOverflowStackView; |
35 @property(nonatomic, assign) BOOL displayOverflowControls; | 40 @property(nonatomic, assign) BOOL displayOverflowControls; |
| 41 @property(nonatomic, strong) ToolbarButton* closeMenuButton; |
| 42 |
| 43 // Sets up the main StackView and creates a button for each Menu item. |
| 44 - (void)setupMenuStackView; |
| 45 // Sets up the Overflow navigation controls stack view. |
| 46 - (void)setUpOverFlowControlsStackView; |
| 47 // Sets up and activates all the View constraints. |
| 48 - (void)setupConstraints; |
36 @end | 49 @end |
37 | 50 |
38 @implementation MenuViewController | 51 @implementation MenuViewController |
39 @synthesize dispatcher = _dispatcher; | 52 @synthesize dispatcher = _dispatcher; |
40 @synthesize menuItems = _menuItems; | 53 @synthesize menuItems = _menuItems; |
41 @synthesize menuStackView = _menuStackView; | 54 @synthesize menuStackView = _menuStackView; |
42 @synthesize toolbarOverflowStackView = _toolbarOverflowStackView; | 55 @synthesize toolbarOverflowStackView = _toolbarOverflowStackView; |
43 @synthesize displayOverflowControls = _displayOverflowControls; | 56 @synthesize displayOverflowControls = _displayOverflowControls; |
| 57 @synthesize menuScrollView = _menuScrollView; |
| 58 @synthesize closeMenuButton = _closeMenuButton; |
| 59 |
| 60 #pragma mark - View Lifecycle |
44 | 61 |
45 - (void)loadView { | 62 - (void)loadView { |
46 CGRect frame; | 63 CGRect frame; |
47 frame.size = CGSizeMake(kMenuWidth, kMenuItemHeight * _menuItems.count); | 64 // Set the MenuVC view height depending on the current screen height. |
| 65 CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height; |
| 66 CGFloat itemsHeight = kMenuItemHeight * _menuItems.count; |
| 67 CGFloat menuHeight = |
| 68 itemsHeight > screenHeight ? screenHeight - kMenuItemHeight : itemsHeight; |
| 69 frame.size = CGSizeMake(kMenuWidth, menuHeight); |
48 frame.origin = CGPointZero; | 70 frame.origin = CGPointZero; |
49 self.view = [[UIView alloc] initWithFrame:frame]; | 71 self.view = [[UIView alloc] initWithFrame:frame]; |
50 self.view.backgroundColor = [UIColor whiteColor]; | 72 self.view.backgroundColor = [UIColor whiteColor]; |
51 self.view.autoresizingMask = UIViewAutoresizingNone; | 73 self.view.autoresizingMask = UIViewAutoresizingNone; |
52 self.view.layer.borderColor = [UIColor clearColor].CGColor; | 74 self.view.layer.borderColor = [UIColor clearColor].CGColor; |
53 } | 75 } |
54 | 76 |
55 - (void)viewDidLoad { | 77 - (void)viewDidLoad { |
| 78 self.menuScrollView = [[UIScrollView alloc] init]; |
| 79 self.menuScrollView.translatesAutoresizingMaskIntoConstraints = NO; |
| 80 [self.view addSubview:self.menuScrollView]; |
| 81 |
| 82 // Add close tools menu button. This button is fixed on the top right corner |
| 83 // and will always be visible. |
| 84 self.closeMenuButton = [ToolbarButton toolsMenuToolbarButton]; |
| 85 [self.closeMenuButton addTarget:self.dispatcher |
| 86 action:@selector(closeToolsMenu) |
| 87 forControlEvents:UIControlEventTouchUpInside]; |
| 88 [self.view addSubview:self.closeMenuButton]; |
| 89 |
| 90 [self setupMenuStackView]; |
| 91 [self setupConstraints]; |
| 92 } |
| 93 |
| 94 #pragma mark - UI Setup |
| 95 |
| 96 - (void)setupMenuStackView { |
56 NSMutableArray<UIButton*>* buttons = | 97 NSMutableArray<UIButton*>* buttons = |
57 [[NSMutableArray alloc] initWithCapacity:_menuItems.count]; | 98 [[NSMutableArray alloc] initWithCapacity:_menuItems.count]; |
58 | |
59 // Load menu items. | 99 // Load menu items. |
60 for (ToolsMenuItem* item in _menuItems) { | 100 for (ToolsMenuItem* item in _menuItems) { |
61 UIButton* menuButton = [UIButton buttonWithType:UIButtonTypeSystem]; | 101 UIButton* menuButton = [UIButton buttonWithType:UIButtonTypeSystem]; |
62 menuButton.translatesAutoresizingMaskIntoConstraints = NO; | 102 menuButton.translatesAutoresizingMaskIntoConstraints = NO; |
63 menuButton.tintColor = [UIColor blackColor]; | 103 menuButton.tintColor = [UIColor blackColor]; |
64 [menuButton setTitle:item.title forState:UIControlStateNormal]; | 104 [menuButton setTitle:item.title forState:UIControlStateNormal]; |
65 [menuButton setContentEdgeInsets:UIEdgeInsetsMakeDirected(0, 10.0f, 0, 0)]; | 105 [menuButton setContentEdgeInsets:UIEdgeInsetsMakeDirected( |
| 106 0, kMenuItemLeadingEdgeInset, 0, 0)]; |
66 [menuButton.titleLabel setFont:[MDCTypography subheadFont]]; | 107 [menuButton.titleLabel setFont:[MDCTypography subheadFont]]; |
67 [menuButton.titleLabel setTextAlignment:NSTextAlignmentNatural]; | 108 [menuButton.titleLabel setTextAlignment:NSTextAlignmentNatural]; |
68 [menuButton addTarget:self.dispatcher | 109 [menuButton addTarget:self.dispatcher |
69 action:@selector(closeToolsMenu) | 110 action:@selector(closeToolsMenu) |
70 forControlEvents:UIControlEventTouchUpInside]; | 111 forControlEvents:UIControlEventTouchUpInside]; |
71 if (item.action) { | 112 if (item.action) { |
72 [menuButton addTarget:self.dispatcher | 113 [menuButton addTarget:self.dispatcher |
73 action:item.action | 114 action:item.action |
74 forControlEvents:UIControlEventTouchUpInside]; | 115 forControlEvents:UIControlEventTouchUpInside]; |
75 } | 116 } |
76 [buttons addObject:menuButton]; | 117 [buttons addObject:menuButton]; |
77 } | 118 } |
78 | 119 |
79 // Placeholder stack view to hold menu contents. | |
80 self.menuStackView = [[UIStackView alloc] initWithArrangedSubviews:buttons]; | 120 self.menuStackView = [[UIStackView alloc] initWithArrangedSubviews:buttons]; |
81 self.menuStackView.translatesAutoresizingMaskIntoConstraints = NO; | 121 self.menuStackView.translatesAutoresizingMaskIntoConstraints = NO; |
82 self.menuStackView.axis = UILayoutConstraintAxisVertical; | 122 self.menuStackView.axis = UILayoutConstraintAxisVertical; |
83 self.menuStackView.distribution = UIStackViewDistributionFillEqually; | 123 self.menuStackView.distribution = UIStackViewDistributionFillEqually; |
84 self.menuStackView.alignment = UIStackViewAlignmentLeading; | 124 self.menuStackView.alignment = UIStackViewAlignmentLeading; |
85 | 125 |
86 // Stack view to hold overflow ToolbarButtons. | 126 // Stack view to hold overflow ToolbarButtons. |
87 if (self.traitCollection.horizontalSizeClass == | 127 if (self.traitCollection.horizontalSizeClass == |
88 UIUserInterfaceSizeClassCompact && | 128 UIUserInterfaceSizeClassCompact && |
89 self.displayOverflowControls) { | 129 self.displayOverflowControls) { |
90 [self setUpOverFlowControlsStackView]; | 130 [self setUpOverFlowControlsStackView]; |
91 } | 131 } |
92 | |
93 // Setup constraints. | |
94 [self.view addSubview:self.menuStackView]; | |
95 [NSLayoutConstraint activateConstraints:@[ | |
96 [self.menuStackView.leadingAnchor | |
97 constraintEqualToAnchor:self.view.leadingAnchor], | |
98 [self.menuStackView.trailingAnchor | |
99 constraintEqualToAnchor:self.view.trailingAnchor], | |
100 [self.menuStackView.bottomAnchor | |
101 constraintEqualToAnchor:self.view.bottomAnchor], | |
102 [self.menuStackView.topAnchor constraintEqualToAnchor:self.view.topAnchor], | |
103 ]]; | |
104 } | 132 } |
105 | 133 |
106 - (void)setUpOverFlowControlsStackView { | 134 - (void)setUpOverFlowControlsStackView { |
107 self.toolbarOverflowStackView = [[MenuOverflowControlsStackView alloc] init]; | 135 self.toolbarOverflowStackView = [[MenuOverflowControlsStackView alloc] init]; |
108 // PLACEHOLDER: ToolsMenuButton might end up being part of the MenuVC's view | 136 // PLACEHOLDER: ToolsMenuButton might end up being part of the MenuVC's view |
109 // instead of the StackView. We are waiting confirmation on this. | 137 // instead of the StackView. We are waiting confirmation on this. |
110 for (UIView* view in self.toolbarOverflowStackView.arrangedSubviews) { | 138 for (UIView* view in self.toolbarOverflowStackView.arrangedSubviews) { |
111 if ([view isKindOfClass:[ToolbarButton class]]) { | 139 if ([view isKindOfClass:[ToolbarButton class]]) { |
112 ToolbarButton* button = base::mac::ObjCCastStrict<ToolbarButton>(view); | 140 ToolbarButton* button = base::mac::ObjCCastStrict<ToolbarButton>(view); |
113 [button addTarget:self.dispatcher | 141 [button addTarget:self.dispatcher |
114 action:@selector(closeToolsMenu) | 142 action:@selector(closeToolsMenu) |
115 forControlEvents:UIControlEventTouchUpInside]; | 143 forControlEvents:UIControlEventTouchUpInside]; |
116 } | 144 } |
117 } | 145 } |
118 [self.toolbarOverflowStackView.reloadButton | 146 [self.toolbarOverflowStackView.reloadButton |
119 addTarget:self.dispatcher | 147 addTarget:self.dispatcher |
120 action:@selector(reloadPage) | 148 action:@selector(reloadPage) |
121 forControlEvents:UIControlEventTouchUpInside]; | 149 forControlEvents:UIControlEventTouchUpInside]; |
122 [self.toolbarOverflowStackView.stopButton | 150 [self.toolbarOverflowStackView.stopButton |
123 addTarget:self.dispatcher | 151 addTarget:self.dispatcher |
124 action:@selector(stopLoadingPage) | 152 action:@selector(stopLoadingPage) |
125 forControlEvents:UIControlEventTouchUpInside]; | 153 forControlEvents:UIControlEventTouchUpInside]; |
126 | 154 |
127 [self.menuStackView insertArrangedSubview:self.toolbarOverflowStackView | 155 [self.menuStackView insertArrangedSubview:self.toolbarOverflowStackView |
128 atIndex:0]; | 156 atIndex:0]; |
129 [NSLayoutConstraint activateConstraints:@[ | 157 [NSLayoutConstraint activateConstraints:@[ |
130 [self.toolbarOverflowStackView.leadingAnchor | 158 [self.toolbarOverflowStackView.leadingAnchor |
131 constraintEqualToAnchor:self.menuStackView.leadingAnchor], | 159 constraintEqualToAnchor:self.menuStackView.leadingAnchor], |
132 [self.toolbarOverflowStackView.trailingAnchor | 160 [self.toolbarOverflowStackView.trailingAnchor |
133 constraintEqualToAnchor:self.menuStackView.trailingAnchor], | 161 constraintEqualToAnchor:self.menuStackView.trailingAnchor |
| 162 constant:-kOverflowControlsMargin], |
134 ]]; | 163 ]]; |
135 } | 164 } |
136 | 165 |
| 166 - (void)setupConstraints { |
| 167 [self.menuScrollView addSubview:self.menuStackView]; |
| 168 [NSLayoutConstraint activateConstraints:@[ |
| 169 // ScrollView Constraints. |
| 170 [self.menuScrollView.leadingAnchor |
| 171 constraintEqualToAnchor:self.view.leadingAnchor], |
| 172 [self.menuScrollView.trailingAnchor |
| 173 constraintEqualToAnchor:self.view.trailingAnchor], |
| 174 [self.menuScrollView.topAnchor constraintEqualToAnchor:self.view.topAnchor], |
| 175 [self.menuScrollView.bottomAnchor |
| 176 constraintEqualToAnchor:self.view.bottomAnchor], |
| 177 // StackView Constraints. |
| 178 [self.menuStackView.leadingAnchor |
| 179 constraintEqualToAnchor:self.menuScrollView.leadingAnchor], |
| 180 [self.menuStackView.trailingAnchor |
| 181 constraintEqualToAnchor:self.menuScrollView.trailingAnchor], |
| 182 [self.menuStackView.bottomAnchor |
| 183 constraintEqualToAnchor:self.menuScrollView.bottomAnchor], |
| 184 [self.menuStackView.topAnchor |
| 185 constraintEqualToAnchor:self.menuScrollView.topAnchor], |
| 186 [self.menuStackView.widthAnchor |
| 187 constraintEqualToAnchor:self.menuScrollView.widthAnchor], |
| 188 [self.menuStackView.heightAnchor |
| 189 constraintEqualToConstant:kMenuItemHeight * self.menuItems.count], |
| 190 // CloseMenu Button Constraints. |
| 191 [self.closeMenuButton.trailingAnchor |
| 192 constraintEqualToAnchor:self.view.trailingAnchor], |
| 193 [self.closeMenuButton.heightAnchor |
| 194 constraintEqualToConstant:kCloseButtonHeight], |
| 195 ]]; |
| 196 } |
| 197 |
137 #pragma mark - Tools Consumer | 198 #pragma mark - Tools Consumer |
138 | 199 |
139 - (void)setToolsMenuItems:(NSArray*)menuItems { | 200 - (void)setToolsMenuItems:(NSArray*)menuItems { |
140 _menuItems = menuItems; | 201 _menuItems = menuItems; |
141 } | 202 } |
142 | 203 |
143 - (void)displayOverflowControls:(BOOL)displayOverflowControls { | 204 - (void)displayOverflowControls:(BOOL)displayOverflowControls { |
144 self.displayOverflowControls = displayOverflowControls; | 205 self.displayOverflowControls = displayOverflowControls; |
145 } | 206 } |
146 | 207 |
147 @end | 208 @end |
OLD | NEW |