Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Side by Side Diff: ios/chrome/browser/ui/collection_view/collection_view_model.mm

Issue 2588713002: Upstream Chrome on iOS source code [4/11]. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #import "ios/chrome/browser/ui/collection_view/collection_view_model.h"
6
7 #include "base/logging.h"
8 #include "base/mac/scoped_nsobject.h"
9 #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h"
10
11 namespace {
12 typedef NSMutableArray<CollectionViewItem*> SectionItems;
13 }
14
15 @implementation CollectionViewModel {
16 // Ordered list of section identifiers, one per section in the model.
17 base::scoped_nsobject<NSMutableArray<NSNumber*>> _sectionIdentifiers;
18
19 // The lists of section items, one per section.
20 base::scoped_nsobject<NSMutableArray<SectionItems*>> _sections;
21
22 // Maps from section identifier to header and footer.
23 base::scoped_nsobject<NSMutableDictionary<NSNumber*, CollectionViewItem*>>
24 _headers;
25 base::scoped_nsobject<NSMutableDictionary<NSNumber*, CollectionViewItem*>>
26 _footers;
27 }
28
29 - (instancetype)init {
30 if ((self = [super init])) {
31 _sectionIdentifiers.reset([[NSMutableArray alloc] init]);
32 _sections.reset([[NSMutableArray alloc] init]);
33 _headers.reset([[NSMutableDictionary alloc] init]);
34 _footers.reset([[NSMutableDictionary alloc] init]);
35 }
36 return self;
37 }
38
39 #pragma mark Modification methods
40
41 - (void)addSectionWithIdentifier:(NSInteger)sectionIdentifier {
42 DCHECK_GE(sectionIdentifier, kSectionIdentifierEnumZero);
43 DCHECK_EQ(static_cast<NSUInteger>(NSNotFound),
44 [self internalSectionForIdentifier:sectionIdentifier]);
45 [_sectionIdentifiers addObject:@(sectionIdentifier)];
46
47 base::scoped_nsobject<SectionItems> section([[SectionItems alloc] init]);
48 [_sections addObject:section];
49 }
50
51 - (void)insertSectionWithIdentifier:(NSInteger)sectionIdentifier
52 atIndex:(NSUInteger)index {
53 DCHECK_GE(sectionIdentifier, kSectionIdentifierEnumZero);
54 DCHECK_EQ(static_cast<NSUInteger>(NSNotFound),
55 [self internalSectionForIdentifier:sectionIdentifier]);
56 DCHECK_LE(index, [_sections count]);
57
58 [_sectionIdentifiers insertObject:@(sectionIdentifier) atIndex:index];
59
60 base::scoped_nsobject<SectionItems> section([[SectionItems alloc] init]);
61 [_sections insertObject:section atIndex:index];
62 }
63
64 - (void)addItem:(CollectionViewItem*)item
65 toSectionWithIdentifier:(NSInteger)sectionIdentifier {
66 DCHECK_GE(item.type, kItemTypeEnumZero);
67 NSInteger section = [self sectionForSectionIdentifier:sectionIdentifier];
68 SectionItems* items = [_sections objectAtIndex:section];
69 [items addObject:item];
70 }
71
72 - (void)insertItem:(CollectionViewItem*)item
73 inSectionWithIdentifier:(NSInteger)sectionIdentifier
74 atIndex:(NSUInteger)index {
75 DCHECK_GE(item.type, kItemTypeEnumZero);
76 NSInteger section = [self sectionForSectionIdentifier:sectionIdentifier];
77 SectionItems* items = [_sections objectAtIndex:section];
78 DCHECK(index <= [items count]);
79 [items insertObject:item atIndex:index];
80 }
81
82 - (void)removeItemWithType:(NSInteger)itemType
83 fromSectionWithIdentifier:(NSInteger)sectionIdentifier {
84 [self removeItemWithType:itemType
85 fromSectionWithIdentifier:sectionIdentifier
86 atIndex:0];
87 }
88
89 - (void)removeItemWithType:(NSInteger)itemType
90 fromSectionWithIdentifier:(NSInteger)sectionIdentifier
91 atIndex:(NSUInteger)index {
92 NSInteger section = [self sectionForSectionIdentifier:sectionIdentifier];
93 SectionItems* items = [_sections objectAtIndex:section];
94 NSInteger item =
95 [self itemForItemType:itemType inSectionItems:items atIndex:index];
96 DCHECK_NE(NSNotFound, item);
97 [items removeObjectAtIndex:item];
98 }
99
100 - (void)removeSectionWithIdentifier:(NSInteger)sectionIdentifier {
101 NSInteger section = [self sectionForSectionIdentifier:sectionIdentifier];
102 [_sectionIdentifiers removeObjectAtIndex:section];
103 [_sections removeObjectAtIndex:section];
104 }
105
106 - (void)setHeader:(CollectionViewItem*)header
107 forSectionWithIdentifier:(NSInteger)sectionIdentifier {
108 NSNumber* key = [NSNumber numberWithInteger:sectionIdentifier];
109 if (header) {
110 [_headers setObject:header forKey:key];
111 } else {
112 [_headers removeObjectForKey:key];
113 }
114 }
115
116 - (void)setFooter:(CollectionViewItem*)footer
117 forSectionWithIdentifier:(NSInteger)sectionIdentifier {
118 NSNumber* key = [NSNumber numberWithInteger:sectionIdentifier];
119 if (footer) {
120 [_footers setObject:footer forKey:key];
121 } else {
122 [_footers removeObjectForKey:key];
123 }
124 }
125
126 #pragma mark Query model coordinates from index paths
127
128 - (NSInteger)sectionIdentifierForSection:(NSInteger)section {
129 DCHECK_LT(static_cast<NSUInteger>(section), [_sectionIdentifiers count]);
130 return [[_sectionIdentifiers objectAtIndex:section] integerValue];
131 }
132
133 - (NSInteger)itemTypeForIndexPath:(NSIndexPath*)indexPath {
134 return [self itemAtIndexPath:indexPath].type;
135 }
136
137 - (NSUInteger)indexInItemTypeForIndexPath:(NSIndexPath*)indexPath {
138 DCHECK_LT(static_cast<NSUInteger>(indexPath.section), [_sections count]);
139 SectionItems* items = [_sections objectAtIndex:indexPath.section];
140
141 CollectionViewItem* item = [self itemAtIndexPath:indexPath];
142 NSUInteger indexInItemType =
143 [self indexInItemTypeForItem:item inSectionItems:items];
144 return indexInItemType;
145 }
146
147 #pragma mark Query items from index paths
148
149 - (BOOL)hasItemAtIndexPath:(NSIndexPath*)indexPath {
150 if (static_cast<NSUInteger>(indexPath.section) < [_sections count]) {
151 SectionItems* items = [_sections objectAtIndex:indexPath.section];
152 return static_cast<NSUInteger>(indexPath.item) < [items count];
153 }
154 return NO;
155 }
156
157 - (CollectionViewItem*)itemAtIndexPath:(NSIndexPath*)indexPath {
158 DCHECK_LT(static_cast<NSUInteger>(indexPath.section), [_sections count]);
159 SectionItems* items = [_sections objectAtIndex:indexPath.section];
160
161 DCHECK_LT(static_cast<NSUInteger>(indexPath.item), [items count]);
162 return [items objectAtIndex:indexPath.item];
163 }
164
165 - (CollectionViewItem*)headerForSection:(NSInteger)section {
166 NSInteger sectionIdentifier = [self sectionIdentifierForSection:section];
167 NSNumber* key = [NSNumber numberWithInteger:sectionIdentifier];
168 return [_headers objectForKey:key];
169 }
170
171 - (CollectionViewItem*)footerForSection:(NSInteger)section {
172 NSInteger sectionIdentifier = [self sectionIdentifierForSection:section];
173 NSNumber* key = [NSNumber numberWithInteger:sectionIdentifier];
174 return [_footers objectForKey:key];
175 }
176
177 - (NSArray*)itemsInSectionWithIdentifier:(NSInteger)sectionIdentifier {
178 NSInteger section = [self sectionForSectionIdentifier:sectionIdentifier];
179 DCHECK_LT(static_cast<NSUInteger>(section), [_sections count]);
180 return [_sections objectAtIndex:section];
181 }
182
183 - (CollectionViewItem*)headerForSectionWithIdentifier:
184 (NSInteger)sectionIdentifier {
185 NSNumber* key = [NSNumber numberWithInteger:sectionIdentifier];
186 return [_headers objectForKey:key];
187 }
188
189 - (CollectionViewItem*)footerForSectionWithIdentifier:
190 (NSInteger)sectionIdentifier {
191 NSNumber* key = [NSNumber numberWithInteger:sectionIdentifier];
192 return [_footers objectForKey:key];
193 }
194
195 #pragma mark Query index paths from model coordinates
196
197 - (BOOL)hasSectionForSectionIdentifier:(NSInteger)sectionIdentifier {
198 NSUInteger section = [self internalSectionForIdentifier:sectionIdentifier];
199 return section != static_cast<NSUInteger>(NSNotFound);
200 }
201
202 - (NSInteger)sectionForSectionIdentifier:(NSInteger)sectionIdentifier {
203 NSUInteger section = [self internalSectionForIdentifier:sectionIdentifier];
204 DCHECK_NE(static_cast<NSUInteger>(NSNotFound), section);
205 return section;
206 }
207
208 - (BOOL)hasItemForItemType:(NSInteger)itemType
209 sectionIdentifier:(NSInteger)sectionIdentifier {
210 return [self hasItemForItemType:itemType
211 sectionIdentifier:sectionIdentifier
212 atIndex:0];
213 }
214
215 - (NSIndexPath*)indexPathForItemType:(NSInteger)itemType
216 sectionIdentifier:(NSInteger)sectionIdentifier {
217 return [self indexPathForItemType:itemType
218 sectionIdentifier:sectionIdentifier
219 atIndex:0];
220 }
221
222 - (BOOL)hasItemForItemType:(NSInteger)itemType
223 sectionIdentifier:(NSInteger)sectionIdentifier
224 atIndex:(NSUInteger)index {
225 if (![self hasSectionForSectionIdentifier:sectionIdentifier]) {
226 return NO;
227 }
228 NSInteger section = [self sectionForSectionIdentifier:sectionIdentifier];
229 SectionItems* items = [_sections objectAtIndex:section];
230 NSInteger item =
231 [self itemForItemType:itemType inSectionItems:items atIndex:index];
232 return item != NSNotFound;
233 }
234
235 - (NSIndexPath*)indexPathForItemType:(NSInteger)itemType
236 sectionIdentifier:(NSInteger)sectionIdentifier
237 atIndex:(NSUInteger)index {
238 NSInteger section = [self sectionForSectionIdentifier:sectionIdentifier];
239 SectionItems* items = [_sections objectAtIndex:section];
240 NSInteger item =
241 [self itemForItemType:itemType inSectionItems:items atIndex:index];
242 return [NSIndexPath indexPathForItem:item inSection:section];
243 }
244
245 #pragma mark Query index paths from items
246
247 - (BOOL)hasItem:(CollectionViewItem*)item
248 inSectionWithIdentifier:(NSInteger)sectionIdentifier {
249 return [[self itemsInSectionWithIdentifier:sectionIdentifier]
250 indexOfObject:item] != NSNotFound;
251 }
252
253 - (NSIndexPath*)indexPathForItem:(CollectionViewItem*)item
254 inSectionWithIdentifier:(NSInteger)sectionIdentifier {
255 NSArray* itemsInSection =
256 [self itemsInSectionWithIdentifier:sectionIdentifier];
257
258 NSInteger section = [self sectionForSectionIdentifier:sectionIdentifier];
259 NSInteger itemIndex = [itemsInSection indexOfObject:item];
260 DCHECK_NE(NSNotFound, itemIndex);
261 return [NSIndexPath indexPathForItem:itemIndex inSection:section];
262 }
263
264 #pragma mark UICollectionView data sourcing
265
266 - (NSInteger)numberOfSections {
267 return [_sections count];
268 }
269
270 - (NSInteger)numberOfItemsInSection:(NSInteger)section {
271 DCHECK_LT(static_cast<NSUInteger>(section), [_sections count]);
272 SectionItems* items = [_sections objectAtIndex:section];
273 return items.count;
274 }
275
276 #pragma mark Private methods
277
278 // Returns the section for the given section identifier. If the section
279 // identifier is not found, NSNotFound is returned.
280 - (NSUInteger)internalSectionForIdentifier:(NSInteger)sectionIdentifier {
281 return [_sectionIdentifiers indexOfObject:@(sectionIdentifier)];
282 }
283
284 // Returns the item for the given item type in the list of items, at the
285 // given index. If no item is found with the given type, NSNotFound is returned.
286 - (NSUInteger)itemForItemType:(NSInteger)itemType
287 inSectionItems:(SectionItems*)sectionItems
288 atIndex:(NSUInteger)index {
289 __block NSUInteger item = NSNotFound;
290 __block NSUInteger indexInItemType = 0;
291 [sectionItems enumerateObjectsUsingBlock:^(CollectionViewItem* obj,
292 NSUInteger idx, BOOL* stop) {
293 if (obj.type == itemType) {
294 if (indexInItemType == index) {
295 item = idx;
296 *stop = YES;
297 } else {
298 indexInItemType++;
299 }
300 }
301 }];
302 return item;
303 }
304
305 // Returns |item|'s index among all the items of the same type in the given
306 // section items. |item| must belong to |sectionItems|.
307 - (NSUInteger)indexInItemTypeForItem:(CollectionViewItem*)item
308 inSectionItems:(SectionItems*)sectionItems {
309 DCHECK([sectionItems containsObject:item]);
310 BOOL found = NO;
311 NSUInteger indexInItemType = 0;
312 for (CollectionViewItem* sectionItem in sectionItems) {
313 if (sectionItem == item) {
314 found = YES;
315 break;
316 }
317 if (sectionItem.type == item.type) {
318 indexInItemType++;
319 }
320 }
321 DCHECK(found);
322 return indexInItemType;
323 }
324
325 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698