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/bookmarks/bookmark_menu_view.h" | 5 #import "ios/chrome/browser/ui/bookmarks/bookmark_menu_view.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/mac/foundation_util.h" | 9 #include "base/mac/foundation_util.h" |
10 #include "base/mac/objc_property_releaser.h" | 10 |
11 #include "base/mac/scoped_nsobject.h" | |
12 #include "components/bookmarks/browser/bookmark_model.h" | 11 #include "components/bookmarks/browser/bookmark_model.h" |
13 #include "components/bookmarks/browser/bookmark_model_observer.h" | 12 #include "components/bookmarks/browser/bookmark_model_observer.h" |
14 #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" | 13 #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" |
15 #include "ios/chrome/browser/bookmarks/bookmarks_utils.h" | 14 #include "ios/chrome/browser/bookmarks/bookmarks_utils.h" |
16 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" | 15 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" |
17 #include "ios/chrome/browser/experimental_flags.h" | 16 #include "ios/chrome/browser/experimental_flags.h" |
18 #import "ios/chrome/browser/ui/bookmarks/bookmark_menu_cell.h" | 17 #import "ios/chrome/browser/ui/bookmarks/bookmark_menu_cell.h" |
19 #import "ios/chrome/browser/ui/bookmarks/bookmark_menu_item.h" | 18 #import "ios/chrome/browser/ui/bookmarks/bookmark_menu_item.h" |
20 #include "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h" | 19 #include "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h" |
21 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" | 20 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" |
22 #include "ios/chrome/browser/ui/ui_util.h" | 21 #include "ios/chrome/browser/ui/ui_util.h" |
23 #import "ios/chrome/browser/ui/uikit_ui_util.h" | 22 #import "ios/chrome/browser/ui/uikit_ui_util.h" |
24 #include "ios/chrome/grit/ios_strings.h" | 23 #include "ios/chrome/grit/ios_strings.h" |
25 #import "ios/third_party/material_components_ios/src/components/Ink/src/Material
Ink.h" | 24 #import "ios/third_party/material_components_ios/src/components/Ink/src/Material
Ink.h" |
26 #include "ui/base/l10n/l10n_util.h" | 25 #include "ui/base/l10n/l10n_util.h" |
27 #include "ui/base/models/tree_node_iterator.h" | 26 #include "ui/base/models/tree_node_iterator.h" |
28 | 27 |
| 28 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 29 #error "This file requires ARC support." |
| 30 #endif |
| 31 |
29 using bookmarks::BookmarkNode; | 32 using bookmarks::BookmarkNode; |
30 | 33 |
31 @interface BookmarkMenuView ()<BookmarkModelBridgeObserver, | 34 @interface BookmarkMenuView ()<BookmarkModelBridgeObserver, |
32 MDCInkTouchControllerDelegate, | 35 MDCInkTouchControllerDelegate, |
33 UITableViewDataSource, | 36 UITableViewDataSource, |
34 UITableViewDelegate> { | 37 UITableViewDelegate> { |
35 // A bridge to receive bookmark model observer callbacks. | 38 // A bridge to receive bookmark model observer callbacks. |
36 std::unique_ptr<bookmarks::BookmarkModelBridge> _modelBridge; | 39 std::unique_ptr<bookmarks::BookmarkModelBridge> _modelBridge; |
37 | |
38 base::mac::ObjCPropertyReleaser _propertyReleaser_BookmarkMenuView; | |
39 } | 40 } |
40 @property(nonatomic, assign) bookmarks::BookmarkModel* bookmarkModel; | 41 @property(nonatomic, assign) bookmarks::BookmarkModel* bookmarkModel; |
41 // This array directly represents the rows that show up in the table. | 42 // This array directly represents the rows that show up in the table. |
42 @property(nonatomic, retain) NSMutableArray* menuItems; | 43 @property(nonatomic, strong) NSMutableArray* menuItems; |
43 // The primary menu item is blue instead of gray. | 44 // The primary menu item is blue instead of gray. |
44 @property(nonatomic, retain) BookmarkMenuItem* primaryMenuItem; | 45 @property(nonatomic, strong) BookmarkMenuItem* primaryMenuItem; |
45 @property(nonatomic, assign) ios::ChromeBrowserState* browserState; | 46 @property(nonatomic, assign) ios::ChromeBrowserState* browserState; |
46 @property(nonatomic, retain) UITableView* tableView; | 47 @property(nonatomic, strong) UITableView* tableView; |
47 @property(nonatomic, retain) MDCInkTouchController* inkTouchController; | 48 @property(nonatomic, strong) MDCInkTouchController* inkTouchController; |
48 | 49 |
49 // Updates the data model, and the UI. | 50 // Updates the data model, and the UI. |
50 - (void)reloadData; | 51 - (void)reloadData; |
51 | 52 |
52 // Creates the views for this class. | 53 // Creates the views for this class. |
53 - (void)createViews; | 54 - (void)createViews; |
54 | 55 |
55 @end | 56 @end |
56 | 57 |
57 @implementation BookmarkMenuView | 58 @implementation BookmarkMenuView |
58 @synthesize bookmarkModel = _bookmarkModel; | 59 @synthesize bookmarkModel = _bookmarkModel; |
59 @synthesize delegate = _delegate; | 60 @synthesize delegate = _delegate; |
60 @synthesize menuItems = _menuItems; | 61 @synthesize menuItems = _menuItems; |
61 @synthesize primaryMenuItem = _primaryMenuItem; | 62 @synthesize primaryMenuItem = _primaryMenuItem; |
62 @synthesize browserState = _browserState; | 63 @synthesize browserState = _browserState; |
63 @synthesize tableView = _tableView; | 64 @synthesize tableView = _tableView; |
64 @synthesize inkTouchController = _inkTouchController; | 65 @synthesize inkTouchController = _inkTouchController; |
65 | 66 |
66 - (id)initWithFrame:(CGRect)frame { | 67 - (id)initWithFrame:(CGRect)frame { |
67 NOTREACHED(); | 68 NOTREACHED(); |
68 return nil; | 69 return nil; |
69 } | 70 } |
70 | 71 |
71 - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState | 72 - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState |
72 frame:(CGRect)frame { | 73 frame:(CGRect)frame { |
73 self = [super initWithFrame:frame]; | 74 self = [super initWithFrame:frame]; |
74 if (self) { | 75 if (self) { |
75 _propertyReleaser_BookmarkMenuView.Init(self, [BookmarkMenuView class]); | |
76 | |
77 _browserState = browserState; | 76 _browserState = browserState; |
78 | 77 |
79 // Set up connection to the BookmarkModel. | 78 // Set up connection to the BookmarkModel. |
80 _bookmarkModel = | 79 _bookmarkModel = |
81 ios::BookmarkModelFactory::GetForBrowserState(_browserState); | 80 ios::BookmarkModelFactory::GetForBrowserState(_browserState); |
82 // Set up observers. | 81 // Set up observers. |
83 _modelBridge.reset( | 82 _modelBridge.reset( |
84 new bookmarks::BookmarkModelBridge(self, _bookmarkModel)); | 83 new bookmarks::BookmarkModelBridge(self, _bookmarkModel)); |
85 | 84 |
86 self.menuItems = [NSMutableArray array]; | 85 self.menuItems = [NSMutableArray array]; |
87 | 86 |
88 [self createViews]; | 87 [self createViews]; |
89 } | 88 } |
90 return self; | 89 return self; |
91 } | 90 } |
92 | 91 |
93 - (void)dealloc { | 92 - (void)dealloc { |
94 self.tableView.delegate = nil; | 93 self.tableView.delegate = nil; |
95 self.tableView.dataSource = nil; | 94 self.tableView.dataSource = nil; |
96 [super dealloc]; | |
97 } | 95 } |
98 | 96 |
99 - (void)createViews { | 97 - (void)createViews { |
100 // Make the table view. | 98 // Make the table view. |
101 self.tableView = base::scoped_nsobject<UITableView>( | 99 self.tableView = [[UITableView alloc] initWithFrame:self.bounds]; |
102 [[UITableView alloc] initWithFrame:self.bounds]); | |
103 [self addSubview:self.tableView]; | 100 [self addSubview:self.tableView]; |
104 self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; | 101 self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; |
105 self.tableView.delegate = self; | 102 self.tableView.delegate = self; |
106 self.tableView.dataSource = self; | 103 self.tableView.dataSource = self; |
107 self.tableView.scrollsToTop = NO; | 104 self.tableView.scrollsToTop = NO; |
108 [self reloadData]; | 105 [self reloadData]; |
109 | 106 |
110 // Set up ink touch controller. | 107 // Set up ink touch controller. |
111 base::scoped_nsobject<MDCInkTouchController> inkTouchController( | 108 MDCInkTouchController* inkTouchController = |
112 [[MDCInkTouchController alloc] initWithView:self.tableView]); | 109 [[MDCInkTouchController alloc] initWithView:self.tableView]; |
113 self.inkTouchController = inkTouchController; | 110 self.inkTouchController = inkTouchController; |
114 self.inkTouchController.delegate = self; | 111 self.inkTouchController.delegate = self; |
115 self.inkTouchController.delaysInkSpread = YES; | 112 self.inkTouchController.delaysInkSpread = YES; |
116 } | 113 } |
117 | 114 |
118 - (void)layoutSubviews { | 115 - (void)layoutSubviews { |
119 [super layoutSubviews]; | 116 [super layoutSubviews]; |
120 self.tableView.frame = self.bounds; | 117 self.tableView.frame = self.bounds; |
121 } | 118 } |
122 | 119 |
123 - (void)reloadData { | 120 - (void)reloadData { |
124 if (!self.bookmarkModel->loaded()) | 121 if (!self.bookmarkModel->loaded()) |
125 return; | 122 return; |
126 | 123 |
127 BookmarkMenuItem* primaryItem = [self.primaryMenuItem parentItem]; | 124 BookmarkMenuItem* primaryItem = [self.primaryMenuItem parentItem]; |
128 | 125 |
129 [self.menuItems removeAllObjects]; | 126 [self.menuItems removeAllObjects]; |
130 | 127 |
131 const BookmarkNode* mobileBookmarks = self.bookmarkModel->mobile_node(); | 128 const BookmarkNode* mobileBookmarks = self.bookmarkModel->mobile_node(); |
132 const BookmarkNode* bookmarkBar = self.bookmarkModel->bookmark_bar_node(); | 129 const BookmarkNode* bookmarkBar = self.bookmarkModel->bookmark_bar_node(); |
133 const BookmarkNode* otherBookmarks = self.bookmarkModel->other_node(); | 130 const BookmarkNode* otherBookmarks = self.bookmarkModel->other_node(); |
134 | 131 |
135 // The first section is always visible. | 132 // The first section is always visible. |
136 base::scoped_nsobject<NSMutableArray> topSection( | 133 NSMutableArray* topSection = [[NSMutableArray alloc] init]; |
137 [[NSMutableArray alloc] init]); | |
138 [self.menuItems addObject:topSection]; | 134 [self.menuItems addObject:topSection]; |
139 | 135 |
140 // Mobile bookmark is shown even if empty. | 136 // Mobile bookmark is shown even if empty. |
141 [topSection | 137 [topSection |
142 addObject:[BookmarkMenuItem folderMenuItemForNode:mobileBookmarks | 138 addObject:[BookmarkMenuItem folderMenuItemForNode:mobileBookmarks |
143 rootAncestor:mobileBookmarks]]; | 139 rootAncestor:mobileBookmarks]]; |
144 // Bookmarks Bar and Other Bookmarks are special folders and are shown at the | 140 // Bookmarks Bar and Other Bookmarks are special folders and are shown at the |
145 // top if they contain anything. | 141 // top if they contain anything. |
146 if (!bookmarkBar->empty()) { | 142 if (!bookmarkBar->empty()) { |
147 [topSection addObject:[BookmarkMenuItem folderMenuItemForNode:bookmarkBar | 143 [topSection addObject:[BookmarkMenuItem folderMenuItemForNode:bookmarkBar |
148 rootAncestor:bookmarkBar]]; | 144 rootAncestor:bookmarkBar]]; |
149 } | 145 } |
150 if (!otherBookmarks->empty()) { | 146 if (!otherBookmarks->empty()) { |
151 [topSection | 147 [topSection |
152 addObject:[BookmarkMenuItem folderMenuItemForNode:otherBookmarks | 148 addObject:[BookmarkMenuItem folderMenuItemForNode:otherBookmarks |
153 rootAncestor:otherBookmarks]]; | 149 rootAncestor:otherBookmarks]]; |
154 } | 150 } |
155 | 151 |
156 // The second section contains all the top level folders (except for the | 152 // The second section contains all the top level folders (except for the |
157 // permanent nodes). | 153 // permanent nodes). |
158 base::scoped_nsobject<NSMutableArray> folderSection( | 154 NSMutableArray* folderSection = [[NSMutableArray alloc] init]; |
159 [[NSMutableArray alloc] init]); | |
160 std::vector<const BookmarkNode*> rootLevelFolders = | 155 std::vector<const BookmarkNode*> rootLevelFolders = |
161 RootLevelFolders(self.bookmarkModel); | 156 RootLevelFolders(self.bookmarkModel); |
162 bookmark_utils_ios::SortFolders(&rootLevelFolders); | 157 bookmark_utils_ios::SortFolders(&rootLevelFolders); |
163 for (auto* node : rootLevelFolders) { | 158 for (auto* node : rootLevelFolders) { |
164 [folderSection addObject:[BookmarkMenuItem folderMenuItemForNode:node | 159 [folderSection addObject:[BookmarkMenuItem folderMenuItemForNode:node |
165 rootAncestor:node]]; | 160 rootAncestor:node]]; |
166 } | 161 } |
167 if ([folderSection count]) { | 162 if ([folderSection count]) { |
168 // Add the title and the divider at the top of the section. | 163 // Add the title and the divider at the top of the section. |
169 [folderSection | 164 [folderSection |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 [self reloadData]; | 300 [self reloadData]; |
306 } | 301 } |
307 | 302 |
308 #pragma mark UITableViewDataSource | 303 #pragma mark UITableViewDataSource |
309 | 304 |
310 - (UITableViewCell*)tableView:(UITableView*)tableView | 305 - (UITableViewCell*)tableView:(UITableView*)tableView |
311 cellForRowAtIndexPath:(NSIndexPath*)indexPath { | 306 cellForRowAtIndexPath:(NSIndexPath*)indexPath { |
312 BookmarkMenuCell* cell = [tableView | 307 BookmarkMenuCell* cell = [tableView |
313 dequeueReusableCellWithIdentifier:[BookmarkMenuCell reuseIdentifier]]; | 308 dequeueReusableCellWithIdentifier:[BookmarkMenuCell reuseIdentifier]]; |
314 if (!cell) { | 309 if (!cell) { |
315 cell = [[[BookmarkMenuCell alloc] | 310 cell = [[BookmarkMenuCell alloc] |
316 initWithStyle:UITableViewCellStyleDefault | 311 initWithStyle:UITableViewCellStyleDefault |
317 reuseIdentifier:[BookmarkMenuCell reuseIdentifier]] autorelease]; | 312 reuseIdentifier:[BookmarkMenuCell reuseIdentifier]]; |
318 } | 313 } |
319 cell.selectionStyle = UITableViewCellSelectionStyleNone; | 314 cell.selectionStyle = UITableViewCellSelectionStyleNone; |
320 BookmarkMenuItem* menuItem = [self menuItemAtIndexPath:indexPath]; | 315 BookmarkMenuItem* menuItem = [self menuItemAtIndexPath:indexPath]; |
321 BOOL primary = | 316 BOOL primary = |
322 [[self.primaryMenuItem parentItem] isEqual:[menuItem parentItem]]; | 317 [[self.primaryMenuItem parentItem] isEqual:[menuItem parentItem]]; |
323 [cell updateWithBookmarkMenuItem:menuItem primary:primary]; | 318 [cell updateWithBookmarkMenuItem:menuItem primary:primary]; |
324 if (primary && bookmark_utils_ios::bookmarkMenuIsInSlideInPanel()) { | 319 if (primary && bookmark_utils_ios::bookmarkMenuIsInSlideInPanel()) { |
325 [tableView selectRowAtIndexPath:indexPath | 320 [tableView selectRowAtIndexPath:indexPath |
326 animated:NO | 321 animated:NO |
327 scrollPosition:UITableViewScrollPositionNone]; | 322 scrollPosition:UITableViewScrollPositionNone]; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 } | 359 } |
365 | 360 |
366 - (CGFloat)tableView:(UITableView*)tableView | 361 - (CGFloat)tableView:(UITableView*)tableView |
367 heightForFooterInSection:(NSInteger)section { | 362 heightForFooterInSection:(NSInteger)section { |
368 BOOL isLastSection = [tableView numberOfSections] == (section + 1); | 363 BOOL isLastSection = [tableView numberOfSections] == (section + 1); |
369 return isLastSection ? 8.0 : 0.0; | 364 return isLastSection ? 8.0 : 0.0; |
370 } | 365 } |
371 | 366 |
372 - (UIView*)tableView:(UITableView*)tableView | 367 - (UIView*)tableView:(UITableView*)tableView |
373 viewForHeaderInSection:(NSInteger)section { | 368 viewForHeaderInSection:(NSInteger)section { |
374 return [[[UIView alloc] initWithFrame:CGRectZero] autorelease]; | 369 return [[UIView alloc] initWithFrame:CGRectZero]; |
375 } | 370 } |
376 | 371 |
377 - (UIView*)tableView:(UITableView*)tableView | 372 - (UIView*)tableView:(UITableView*)tableView |
378 viewForFooterInSection:(NSInteger)section { | 373 viewForFooterInSection:(NSInteger)section { |
379 return [[[UIView alloc] initWithFrame:CGRectZero] autorelease]; | 374 return [[UIView alloc] initWithFrame:CGRectZero]; |
380 } | 375 } |
381 | 376 |
382 #pragma mark MDCInkTouchControllerDelegate | 377 #pragma mark MDCInkTouchControllerDelegate |
383 | 378 |
384 - (BOOL)inkTouchController:(MDCInkTouchController*)inkTouchController | 379 - (BOOL)inkTouchController:(MDCInkTouchController*)inkTouchController |
385 shouldProcessInkTouchesAtTouchLocation:(CGPoint)location { | 380 shouldProcessInkTouchesAtTouchLocation:(CGPoint)location { |
386 NSIndexPath* indexPath = [self.tableView indexPathForRowAtPoint:location]; | 381 NSIndexPath* indexPath = [self.tableView indexPathForRowAtPoint:location]; |
387 BookmarkMenuItem* menuItem = [self menuItemAtIndexPath:indexPath]; | 382 BookmarkMenuItem* menuItem = [self menuItemAtIndexPath:indexPath]; |
388 return menuItem.type == bookmarks::MenuItemFolder; | 383 return menuItem.type == bookmarks::MenuItemFolder; |
389 } | 384 } |
(...skipping 14 matching lines...) Expand all Loading... |
404 | 399 |
405 self.primaryMenuItem = menuItem; | 400 self.primaryMenuItem = menuItem; |
406 [self.tableView reloadData]; | 401 [self.tableView reloadData]; |
407 } | 402 } |
408 | 403 |
409 - (void)setScrollsToTop:(BOOL)scrollsToTop { | 404 - (void)setScrollsToTop:(BOOL)scrollsToTop { |
410 self.tableView.scrollsToTop = scrollsToTop; | 405 self.tableView.scrollsToTop = scrollsToTop; |
411 } | 406 } |
412 | 407 |
413 @end | 408 @end |
OLD | NEW |