| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/chrome/browser/ui/tools_menu/tools_menu_view_controller.h" | 5 #import "ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include "base/ios/ios_util.h" | 9 #include "base/ios/ios_util.h" |
| 10 #import "base/ios/weak_nsobject.h" | 10 #import "base/ios/weak_nsobject.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/mac/objc_property_releaser.h" | 12 #include "base/mac/objc_property_releaser.h" |
| 13 #include "base/mac/scoped_nsobject.h" | 13 #include "base/mac/scoped_nsobject.h" |
| 14 #include "base/metrics/field_trial.h" | 14 #include "base/metrics/field_trial.h" |
| 15 #include "components/reading_list/core/reading_list_switches.h" | |
| 16 #include "components/strings/grit/components_strings.h" | |
| 17 #include "ios/chrome/browser/experimental_flags.h" | |
| 18 #import "ios/chrome/browser/ui/animation_util.h" | 15 #import "ios/chrome/browser/ui/animation_util.h" |
| 19 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" | 16 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" |
| 20 #include "ios/chrome/browser/ui/commands/ios_command_ids.h" | 17 #include "ios/chrome/browser/ui/commands/ios_command_ids.h" |
| 21 #import "ios/chrome/browser/ui/reading_list/reading_list_menu_notification_deleg
ate.h" | 18 #import "ios/chrome/browser/ui/reading_list/reading_list_menu_notification_deleg
ate.h" |
| 22 #import "ios/chrome/browser/ui/reading_list/reading_list_menu_notifier.h" | 19 #import "ios/chrome/browser/ui/reading_list/reading_list_menu_notifier.h" |
| 23 #import "ios/chrome/browser/ui/tools_menu/reading_list_menu_view_item.h" | 20 #import "ios/chrome/browser/ui/tools_menu/reading_list_menu_view_item.h" |
| 24 #import "ios/chrome/browser/ui/tools_menu/tools_menu_context.h" | 21 #import "ios/chrome/browser/ui/tools_menu/tools_menu_context.h" |
| 22 #include "ios/chrome/browser/ui/tools_menu/tools_menu_model.h" |
| 25 #import "ios/chrome/browser/ui/tools_menu/tools_menu_view_item.h" | 23 #import "ios/chrome/browser/ui/tools_menu/tools_menu_view_item.h" |
| 26 #import "ios/chrome/browser/ui/tools_menu/tools_menu_view_tools_cell.h" | 24 #import "ios/chrome/browser/ui/tools_menu/tools_menu_view_tools_cell.h" |
| 27 #import "ios/chrome/browser/ui/tools_menu/tools_popup_controller.h" | 25 #import "ios/chrome/browser/ui/tools_menu/tools_popup_controller.h" |
| 28 #include "ios/chrome/browser/ui/ui_util.h" | |
| 29 #import "ios/chrome/browser/ui/uikit_ui_util.h" | 26 #import "ios/chrome/browser/ui/uikit_ui_util.h" |
| 30 #import "ios/chrome/common/material_timing.h" | 27 #import "ios/chrome/common/material_timing.h" |
| 31 #include "ios/chrome/grit/ios_strings.h" | 28 #include "ios/chrome/grit/ios_strings.h" |
| 32 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" | |
| 33 #import "ios/public/provider/chrome/browser/user_feedback/user_feedback_provider
.h" | |
| 34 #import "ios/third_party/material_components_ios/src/components/Ink/src/Material
Ink.h" | 29 #import "ios/third_party/material_components_ios/src/components/Ink/src/Material
Ink.h" |
| 35 #include "ui/base/l10n/l10n_util.h" | 30 #include "ui/base/l10n/l10n_util.h" |
| 36 #include "ui/base/l10n/l10n_util_mac.h" | 31 #include "ui/base/l10n/l10n_util_mac.h" |
| 37 | 32 |
| 38 using ios::material::TimingFunction; | 33 using ios::material::TimingFunction; |
| 39 | 34 |
| 40 NSString* const kToolsMenuNewTabId = @"kToolsMenuNewTabId"; | |
| 41 NSString* const kToolsMenuNewIncognitoTabId = @"kToolsMenuNewIncognitoTabId"; | |
| 42 NSString* const kToolsMenuCloseAllTabsId = @"kToolsMenuCloseAllTabsId"; | |
| 43 NSString* const kToolsMenuCloseAllIncognitoTabsId = | |
| 44 @"kToolsMenuCloseAllIncognitoTabsId"; | |
| 45 NSString* const kToolsMenuBookmarksId = @"kToolsMenuBookmarksId"; | |
| 46 NSString* const kToolsMenuReadingListId = @"kToolsMenuReadingListId"; | |
| 47 NSString* const kToolsMenuOtherDevicesId = @"kToolsMenuOtherDevicesId"; | |
| 48 NSString* const kToolsMenuHistoryId = @"kToolsMenuHistoryId"; | |
| 49 NSString* const kToolsMenuReportAnIssueId = @"kToolsMenuReportAnIssueId"; | |
| 50 NSString* const kToolsMenuFindInPageId = @"kToolsMenuFindInPageId"; | |
| 51 NSString* const kToolsMenuReaderMode = @"kToolsMenuReaderMode"; | |
| 52 NSString* const kToolsMenuRequestDesktopId = @"kToolsMenuRequestDesktopId"; | |
| 53 NSString* const kToolsMenuSettingsId = @"kToolsMenuSettingsId"; | |
| 54 NSString* const kToolsMenuHelpId = @"kToolsMenuHelpId"; | |
| 55 NSString* const kToolsMenuSuggestionsId = @"kToolsMenuSuggestionsId"; | |
| 56 | |
| 57 namespace { | 35 namespace { |
| 58 | 36 |
| 59 // Time for ink to fade into view. | 37 // Time for ink to fade into view. |
| 60 static const NSTimeInterval kMDCInkTouchDelayInterval = 0.15; | 38 static const NSTimeInterval kMDCInkTouchDelayInterval = 0.15; |
| 61 | 39 |
| 62 static const CGFloat kMenuItemHeight = 48; | 40 static const CGFloat kMenuItemHeight = 48; |
| 63 | 41 |
| 64 static NSString* const kToolsItemCellID = @"ToolsItemCellID"; | 42 static NSString* const kToolsItemCellID = @"ToolsItemCellID"; |
| 65 | 43 |
| 66 // Menu items can be marked as visible or not when Incognito is enabled. | |
| 67 // The following bits are used for |visibility| field in |MenuItemInfo|. | |
| 68 const NSInteger kVisibleIncognitoOnly = 1 << 0; | |
| 69 const NSInteger kVisibleNotIncognitoOnly = 1 << 1; | |
| 70 | |
| 71 // Initialization table for all possible commands to initialize the | |
| 72 // tools menu at run time. Data initialized into this structure is not mutable. | |
| 73 struct MenuItemInfo { | |
| 74 int title_id; | |
| 75 NSString* accessibility_id; | |
| 76 int command_id; | |
| 77 int toolbar_types; | |
| 78 // |visibility| is applied if a menu item is included for a given | |
| 79 // |toolbar_types|. A value of 0 means the menu item is always visible for | |
| 80 // the given |toolbar_types|. | |
| 81 int visibility; | |
| 82 // Custom class, if any, for the menu item, or |nil|. | |
| 83 Class item_class; | |
| 84 }; | |
| 85 | |
| 86 // Flags for different toolbar types | |
| 87 typedef NS_OPTIONS(NSUInteger, kToolbarType) { | |
| 88 // clang-format off | |
| 89 kToolbarTypeNone = 0, | |
| 90 kToolbarTypeWebiPhone = 1 << 0, | |
| 91 kToolbarTypeWebiPad = 1 << 1, | |
| 92 kToolbarTypeNoTabsiPad = 1 << 2, | |
| 93 kToolbarTypeSwitcheriPhone = 1 << 3, | |
| 94 kToolbarTypeWebAll = kToolbarTypeWebiPhone | kToolbarTypeWebiPad, | |
| 95 kToolbarTypeAll = kToolbarTypeWebAll | | |
| 96 kToolbarTypeSwitcheriPhone | | |
| 97 kToolbarTypeNoTabsiPad, | |
| 98 // clang-format on | |
| 99 }; | |
| 100 | |
| 101 // Declare all the possible items. | |
| 102 static MenuItemInfo itemInfoList[] = { | |
| 103 // clang-format off | |
| 104 { IDS_IOS_TOOLS_MENU_NEW_TAB, kToolsMenuNewTabId, | |
| 105 IDC_NEW_TAB, kToolbarTypeAll, | |
| 106 0, nil }, | |
| 107 { IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB, kToolsMenuNewIncognitoTabId, | |
| 108 IDC_NEW_INCOGNITO_TAB, kToolbarTypeAll, | |
| 109 0, nil }, | |
| 110 { IDS_IOS_TOOLS_MENU_CLOSE_ALL_TABS, kToolsMenuCloseAllTabsId, | |
| 111 IDC_CLOSE_ALL_TABS, kToolbarTypeSwitcheriPhone, | |
| 112 kVisibleNotIncognitoOnly, nil }, | |
| 113 { IDS_IOS_TOOLS_MENU_CLOSE_ALL_INCOGNITO_TABS, | |
| 114 kToolsMenuCloseAllIncognitoTabsId, | |
| 115 IDC_CLOSE_ALL_INCOGNITO_TABS, kToolbarTypeSwitcheriPhone, | |
| 116 kVisibleIncognitoOnly, nil }, | |
| 117 { IDS_IOS_TOOLS_MENU_BOOKMARKS, kToolsMenuBookmarksId, | |
| 118 IDC_SHOW_BOOKMARK_MANAGER, kToolbarTypeWebAll, | |
| 119 0, nil }, | |
| 120 { IDS_IOS_TOOLS_MENU_READING_LIST, kToolsMenuReadingListId, | |
| 121 IDC_SHOW_READING_LIST, kToolbarTypeWebAll, | |
| 122 0, [ReadingListMenuViewItem class] }, | |
| 123 { IDS_IOS_TOOLS_MENU_SUGGESTIONS, kToolsMenuSuggestionsId, | |
| 124 IDC_SHOW_SUGGESTIONS, kToolbarTypeWebAll, | |
| 125 0, nil }, | |
| 126 { IDS_IOS_TOOLS_MENU_RECENT_TABS, kToolsMenuOtherDevicesId, | |
| 127 IDC_SHOW_OTHER_DEVICES, kToolbarTypeWebAll, | |
| 128 kVisibleNotIncognitoOnly, nil }, | |
| 129 { IDS_HISTORY_SHOW_HISTORY, kToolsMenuHistoryId, | |
| 130 IDC_SHOW_HISTORY, kToolbarTypeWebAll, | |
| 131 0, nil }, | |
| 132 { IDS_IOS_OPTIONS_REPORT_AN_ISSUE, kToolsMenuReportAnIssueId, | |
| 133 IDC_REPORT_AN_ISSUE, kToolbarTypeAll, | |
| 134 0, nil }, | |
| 135 { IDS_IOS_TOOLS_MENU_FIND_IN_PAGE, kToolsMenuFindInPageId, | |
| 136 IDC_FIND, kToolbarTypeWebAll, | |
| 137 0, nil }, | |
| 138 { IDS_IOS_TOOLS_MENU_REQUEST_DESKTOP_SITE, kToolsMenuRequestDesktopId, | |
| 139 IDC_REQUEST_DESKTOP_SITE, kToolbarTypeWebAll, | |
| 140 0, nil }, | |
| 141 { IDS_IOS_TOOLS_MENU_READER_MODE, kToolsMenuReaderMode, | |
| 142 IDC_READER_MODE, kToolbarTypeWebAll, | |
| 143 0, nil }, | |
| 144 { IDS_IOS_TOOLS_MENU_SETTINGS, kToolsMenuSettingsId, | |
| 145 IDC_OPTIONS, kToolbarTypeAll, | |
| 146 0, nil }, | |
| 147 { IDS_IOS_TOOLS_MENU_HELP_MOBILE, kToolsMenuHelpId, | |
| 148 IDC_HELP_PAGE_VIA_MENU, kToolbarTypeWebAll, | |
| 149 0, nil }, | |
| 150 // clang-format on | |
| 151 }; | |
| 152 | |
| 153 NS_INLINE BOOL ItemShouldBeVisible(const MenuItemInfo& item, | |
| 154 BOOL incognito, | |
| 155 kToolbarType toolbarType) { | |
| 156 if (!(item.toolbar_types & toolbarType)) | |
| 157 return NO; | |
| 158 | |
| 159 if (incognito && (item.visibility & kVisibleNotIncognitoOnly)) | |
| 160 return NO; | |
| 161 | |
| 162 if (!incognito && (item.visibility & kVisibleIncognitoOnly)) | |
| 163 return NO; | |
| 164 | |
| 165 if (item.title_id == IDS_IOS_TOOLBAR_SHOW_TABS) { | |
| 166 if (!IsIPadIdiom()) { | |
| 167 return NO; | |
| 168 } | |
| 169 } | |
| 170 | |
| 171 if (item.title_id == IDS_IOS_TOOLS_MENU_READER_MODE) { | |
| 172 if (!experimental_flags::IsReaderModeEnabled()) { | |
| 173 return NO; | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 if (item.title_id == IDS_IOS_TOOLS_MENU_READING_LIST) { | |
| 178 if (!reading_list::switches::IsReadingListEnabled()) { | |
| 179 return NO; | |
| 180 } | |
| 181 } | |
| 182 | |
| 183 if (item.title_id == IDS_IOS_TOOLS_MENU_SUGGESTIONS) { | |
| 184 if (!experimental_flags::IsSuggestionsUIEnabled()) { | |
| 185 return NO; | |
| 186 } | |
| 187 } | |
| 188 | |
| 189 if (item.title_id == IDS_IOS_OPTIONS_REPORT_AN_ISSUE) { | |
| 190 if (!ios::GetChromeBrowserProvider() | |
| 191 ->GetUserFeedbackProvider() | |
| 192 ->IsUserFeedbackEnabled()) { | |
| 193 return NO; | |
| 194 } | |
| 195 } | |
| 196 | |
| 197 return YES; | |
| 198 } | |
| 199 | |
| 200 NS_INLINE void AnimateInViews(NSArray* views, | 44 NS_INLINE void AnimateInViews(NSArray* views, |
| 201 CGFloat initialX, | 45 CGFloat initialX, |
| 202 CGFloat initialY) { | 46 CGFloat initialY) { |
| 203 [views enumerateObjectsUsingBlock:^(UIView* view, NSUInteger index, | 47 [views enumerateObjectsUsingBlock:^(UIView* view, NSUInteger index, |
| 204 BOOL* stop) { | 48 BOOL* stop) { |
| 205 CGFloat beginTime = index * .035; | 49 CGFloat beginTime = index * .035; |
| 206 CABasicAnimation* transformAnimation = | 50 CABasicAnimation* transformAnimation = |
| 207 [CABasicAnimation animationWithKeyPath:@"transform"]; | 51 [CABasicAnimation animationWithKeyPath:@"transform"]; |
| 208 [transformAnimation | 52 [transformAnimation |
| 209 setFromValue:[NSValue | 53 setFromValue:[NSValue |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 DCHECK(!context.hasNoOpenedTabs || context.isInTabSwitcher); | 222 DCHECK(!context.hasNoOpenedTabs || context.isInTabSwitcher); |
| 379 _toolbarType = context.isInTabSwitcher ? kToolbarTypeSwitcheriPhone | 223 _toolbarType = context.isInTabSwitcher ? kToolbarTypeSwitcheriPhone |
| 380 : kToolbarTypeWebiPhone; | 224 : kToolbarTypeWebiPhone; |
| 381 } | 225 } |
| 382 | 226 |
| 383 // Build the menu, adding all relevant items. | 227 // Build the menu, adding all relevant items. |
| 384 NSMutableArray* menu = [NSMutableArray array]; | 228 NSMutableArray* menu = [NSMutableArray array]; |
| 385 | 229 |
| 386 for (size_t i = 0; i < arraysize(itemInfoList); ++i) { | 230 for (size_t i = 0; i < arraysize(itemInfoList); ++i) { |
| 387 const MenuItemInfo& item = itemInfoList[i]; | 231 const MenuItemInfo& item = itemInfoList[i]; |
| 388 if (!ItemShouldBeVisible(item, context.isInIncognito, _toolbarType)) | 232 if (!ToolsMenuItemShouldBeVisible(item, context.isInIncognito, |
| 233 _toolbarType)) |
| 389 continue; | 234 continue; |
| 390 | 235 |
| 391 NSString* title = l10n_util::GetNSStringWithFixup(item.title_id); | 236 NSString* title = l10n_util::GetNSStringWithFixup(item.title_id); |
| 392 Class itemClass = | 237 Class itemClass = |
| 393 item.item_class ? item.item_class : [ToolsMenuViewItem class]; | 238 item.item_class ? item.item_class : [ToolsMenuViewItem class]; |
| 394 // Sanity check that the class is a useful one. | 239 // Sanity check that the class is a useful one. |
| 395 DCHECK([itemClass respondsToSelector:@selector(menuItemWithTitle: | 240 DCHECK([itemClass respondsToSelector:@selector(menuItemWithTitle: |
| 396 accessibilityIdentifier: | 241 accessibilityIdentifier: |
| 397 command:)]); | 242 command:)]); |
| 398 [menu addObject:[itemClass menuItemWithTitle:title | 243 [menu addObject:[itemClass menuItemWithTitle:title |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 | 592 |
| 748 - (void)unreadCountChanged:(NSInteger)unreadCount { | 593 - (void)unreadCountChanged:(NSInteger)unreadCount { |
| 749 [[self readingListCell] updateBadgeCount:unreadCount animated:YES]; | 594 [[self readingListCell] updateBadgeCount:unreadCount animated:YES]; |
| 750 } | 595 } |
| 751 | 596 |
| 752 - (void)unseenStateChanged:(BOOL)unseenItemsExist { | 597 - (void)unseenStateChanged:(BOOL)unseenItemsExist { |
| 753 [[self readingListCell] updateSeenState:unseenItemsExist animated:YES]; | 598 [[self readingListCell] updateSeenState:unseenItemsExist animated:YES]; |
| 754 } | 599 } |
| 755 | 600 |
| 756 @end | 601 @end |
| OLD | NEW |