| 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/history/tab_history_view_controller.h" | 5 #import "ios/chrome/browser/ui/history/tab_history_view_controller.h" | 
| 6 | 6 | 
| 7 #import "base/ios/weak_nsobject.h" |  | 
| 8 #include "base/logging.h" | 7 #include "base/logging.h" | 
| 9 #include "base/mac/foundation_util.h" | 8 #include "base/mac/foundation_util.h" | 
| 10 #include "base/mac/objc_property_releaser.h" |  | 
| 11 #include "base/mac/scoped_nsobject.h" |  | 
| 12 #include "base/strings/sys_string_conversions.h" | 9 #include "base/strings/sys_string_conversions.h" | 
| 13 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" | 10 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" | 
| 14 #include "ios/chrome/browser/ui/commands/ios_command_ids.h" | 11 #include "ios/chrome/browser/ui/commands/ios_command_ids.h" | 
| 15 #import "ios/chrome/browser/ui/history/tab_history_cell.h" | 12 #import "ios/chrome/browser/ui/history/tab_history_cell.h" | 
| 16 #include "ios/chrome/browser/ui/rtl_geometry.h" | 13 #include "ios/chrome/browser/ui/rtl_geometry.h" | 
| 17 #import "ios/third_party/material_components_ios/src/components/Ink/src/Material
     Ink.h" | 14 #import "ios/third_party/material_components_ios/src/components/Ink/src/Material
     Ink.h" | 
| 18 #import "ios/web/navigation/crw_session_entry.h" | 15 #import "ios/web/navigation/crw_session_entry.h" | 
| 19 #include "ios/web/public/favicon_status.h" | 16 #include "ios/web/public/favicon_status.h" | 
| 20 #include "ios/web/public/navigation_item.h" | 17 #include "ios/web/public/navigation_item.h" | 
| 21 #include "ui/gfx/image/image.h" | 18 #include "ui/gfx/image/image.h" | 
| 22 | 19 | 
|  | 20 #if !defined(__has_feature) || !__has_feature(objc_arc) | 
|  | 21 #error "This file requires ARC support." | 
|  | 22 #endif | 
|  | 23 | 
| 23 namespace { | 24 namespace { | 
| 24 | 25 | 
| 25 // Visible percentage of the last visible row on the Tools menu if the | 26 // Visible percentage of the last visible row on the Tools menu if the | 
| 26 // Tools menu is scrollable. | 27 // Tools menu is scrollable. | 
| 27 const CGFloat kLastRowVisiblePercentage = 0.6; | 28 const CGFloat kLastRowVisiblePercentage = 0.6; | 
| 28 // Reuse identifier for cells. | 29 // Reuse identifier for cells. | 
| 29 NSString* cellIdentifier = @"TabHistoryCell"; | 30 NSString* cellIdentifier = @"TabHistoryCell"; | 
| 30 NSString* footerIdentifier = @"Footer"; | 31 NSString* footerIdentifier = @"Footer"; | 
| 31 NSString* headerIdentifier = @"Header"; | 32 NSString* headerIdentifier = @"Header"; | 
| 32 // Height of rows. | 33 // Height of rows. | 
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 210     [attributes setFrame:LayoutRectGetRect(cellLayout)]; | 211     [attributes setFrame:LayoutRectGetRect(cellLayout)]; | 
| 211     [attributes setZIndex:0]; | 212     [attributes setZIndex:0]; | 
| 212   } | 213   } | 
| 213 | 214 | 
| 214   return attributes; | 215   return attributes; | 
| 215 } | 216 } | 
| 216 | 217 | 
| 217 @end | 218 @end | 
| 218 | 219 | 
| 219 @interface TabHistoryViewController ()<MDCInkTouchControllerDelegate> { | 220 @interface TabHistoryViewController ()<MDCInkTouchControllerDelegate> { | 
| 220   base::scoped_nsobject<MDCInkTouchController> _inkTouchController; | 221   MDCInkTouchController* _inkTouchController; | 
| 221   base::scoped_nsobject<NSArray> _partitionedEntries; | 222   NSArray* _partitionedEntries; | 
| 222   base::scoped_nsobject<NSArray> _sessionEntries; | 223   NSArray* _sessionEntries; | 
| 223 } | 224 } | 
| 224 @end | 225 @end | 
| 225 | 226 | 
| 226 @implementation TabHistoryViewController | 227 @implementation TabHistoryViewController | 
| 227 | 228 | 
| 228 - (NSArray*)sessionEntries { | 229 - (NSArray*)sessionEntries { | 
| 229   return [[_sessionEntries retain] autorelease]; | 230   return _sessionEntries; | 
| 230 } | 231 } | 
| 231 | 232 | 
| 232 #pragma mark Public Methods | 233 #pragma mark Public Methods | 
| 233 | 234 | 
| 234 - (CGFloat)optimalHeight:(CGFloat)suggestedHeight { | 235 - (CGFloat)optimalHeight:(CGFloat)suggestedHeight { | 
| 235   DCHECK(suggestedHeight >= kCellHeight); | 236   DCHECK(suggestedHeight >= kCellHeight); | 
| 236   CGFloat optimalHeight = 0; | 237   CGFloat optimalHeight = 0; | 
| 237 | 238 | 
| 238   for (NSArray* sectionArray in _partitionedEntries.get()) { | 239   for (NSArray* sectionArray in _partitionedEntries) { | 
| 239     NSUInteger sectionItemCount = [sectionArray count]; | 240     NSUInteger sectionItemCount = [sectionArray count]; | 
| 240     for (NSUInteger i = 0; i < sectionItemCount; ++i) { | 241     for (NSUInteger i = 0; i < sectionItemCount; ++i) { | 
| 241       CGFloat proposedHeight = optimalHeight + kCellHeight; | 242       CGFloat proposedHeight = optimalHeight + kCellHeight; | 
| 242 | 243 | 
| 243       if (proposedHeight > suggestedHeight) { | 244       if (proposedHeight > suggestedHeight) { | 
| 244         CGFloat difference = proposedHeight - suggestedHeight; | 245         CGFloat difference = proposedHeight - suggestedHeight; | 
| 245         if (difference > kCellHeightLastRow) { | 246         if (difference > kCellHeightLastRow) { | 
| 246           return optimalHeight + kCellHeightLastRow; | 247           return optimalHeight + kCellHeightLastRow; | 
| 247         } else { | 248         } else { | 
| 248           return optimalHeight - kCellHeight + kCellHeightLastRow; | 249           return optimalHeight - kCellHeight + kCellHeightLastRow; | 
| 249         } | 250         } | 
| 250       } | 251       } | 
| 251 | 252 | 
| 252       optimalHeight = proposedHeight; | 253       optimalHeight = proposedHeight; | 
| 253     } | 254     } | 
| 254 | 255 | 
| 255     optimalHeight += FooterHeight(); | 256     optimalHeight += FooterHeight(); | 
| 256   } | 257   } | 
| 257 | 258 | 
| 258   // If this point is reached, it means the entire content fits and this last | 259   // If this point is reached, it means the entire content fits and this last | 
| 259   // section should not include the footer. | 260   // section should not include the footer. | 
| 260   optimalHeight -= FooterHeight(); | 261   optimalHeight -= FooterHeight(); | 
| 261 | 262 | 
| 262   return optimalHeight; | 263   return optimalHeight; | 
| 263 } | 264 } | 
| 264 | 265 | 
| 265 - (instancetype)init { | 266 - (instancetype)init { | 
| 266   base::scoped_nsobject<TabHistoryViewControllerLayout> layout( | 267   TabHistoryViewControllerLayout* layout = | 
| 267       [[TabHistoryViewControllerLayout alloc] init]); | 268       [[TabHistoryViewControllerLayout alloc] init]; | 
| 268 | 269 | 
| 269   return [self initWithCollectionViewLayout:layout]; | 270   return [self initWithCollectionViewLayout:layout]; | 
| 270 } | 271 } | 
| 271 | 272 | 
| 272 - (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout*)layout { | 273 - (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout*)layout { | 
| 273   self = [super initWithCollectionViewLayout:layout]; | 274   self = [super initWithCollectionViewLayout:layout]; | 
| 274   if (self) { | 275   if (self) { | 
| 275     UICollectionView* collectionView = [self collectionView]; | 276     UICollectionView* collectionView = [self collectionView]; | 
| 276     [collectionView setBackgroundColor:[UIColor whiteColor]]; | 277     [collectionView setBackgroundColor:[UIColor whiteColor]]; | 
| 277 | 278 | 
| 278     [collectionView registerClass:[TabHistoryCell class] | 279     [collectionView registerClass:[TabHistoryCell class] | 
| 279         forCellWithReuseIdentifier:cellIdentifier]; | 280         forCellWithReuseIdentifier:cellIdentifier]; | 
| 280 | 281 | 
| 281     [collectionView registerClass:[TabHistorySectionHeader class] | 282     [collectionView registerClass:[TabHistorySectionHeader class] | 
| 282         forSupplementaryViewOfKind:UICollectionElementKindSectionHeader | 283         forSupplementaryViewOfKind:UICollectionElementKindSectionHeader | 
| 283                withReuseIdentifier:headerIdentifier]; | 284                withReuseIdentifier:headerIdentifier]; | 
| 284 | 285 | 
| 285     [collectionView registerClass:[TabHistorySectionFooter class] | 286     [collectionView registerClass:[TabHistorySectionFooter class] | 
| 286         forSupplementaryViewOfKind:UICollectionElementKindSectionFooter | 287         forSupplementaryViewOfKind:UICollectionElementKindSectionFooter | 
| 287                withReuseIdentifier:footerIdentifier]; | 288                withReuseIdentifier:footerIdentifier]; | 
| 288 | 289 | 
| 289     _inkTouchController.reset( | 290     _inkTouchController = | 
| 290         [[MDCInkTouchController alloc] initWithView:collectionView]); | 291         [[MDCInkTouchController alloc] initWithView:collectionView]; | 
| 291     [_inkTouchController setDelegate:self]; | 292     [_inkTouchController setDelegate:self]; | 
| 292     [_inkTouchController addInkView]; | 293     [_inkTouchController addInkView]; | 
| 293   } | 294   } | 
| 294 | 295 | 
| 295   return self; | 296   return self; | 
| 296 } | 297 } | 
| 297 | 298 | 
| 298 #pragma mark UICollectionViewDelegate | 299 #pragma mark UICollectionViewDelegate | 
| 299 | 300 | 
| 300 - (void)collectionView:(UICollectionView*)collectionView | 301 - (void)collectionView:(UICollectionView*)collectionView | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 363     iconImage = image.ToUIImage(); | 364     iconImage = image.ToUIImage(); | 
| 364   else | 365   else | 
| 365     iconImage = [UIImage imageNamed:@"default_favicon"]; | 366     iconImage = [UIImage imageNamed:@"default_favicon"]; | 
| 366 | 367 | 
| 367   [[header iconView] setImage:iconImage]; | 368   [[header iconView] setImage:iconImage]; | 
| 368 | 369 | 
| 369   return header; | 370   return header; | 
| 370 } | 371 } | 
| 371 | 372 | 
| 372 - (void)setSessionEntries:(NSArray*)sessionEntries { | 373 - (void)setSessionEntries:(NSArray*)sessionEntries { | 
| 373   _sessionEntries.reset([sessionEntries retain]); | 374   _sessionEntries = sessionEntries; | 
| 374 | 375 | 
| 375   std::string previousHost; | 376   std::string previousHost; | 
| 376 | 377 | 
| 377   NSMutableArray* sectionArray = [NSMutableArray array]; | 378   NSMutableArray* sectionArray = [NSMutableArray array]; | 
| 378   NSMutableArray* partitionedEntries = [NSMutableArray array]; | 379   NSMutableArray* partitionedEntries = [NSMutableArray array]; | 
| 379 | 380 | 
| 380   NSInteger numberOfEntries = [_sessionEntries count]; | 381   NSInteger numberOfEntries = [_sessionEntries count]; | 
| 381   for (NSInteger index = 0; index < numberOfEntries; ++index) { | 382   for (NSInteger index = 0; index < numberOfEntries; ++index) { | 
| 382     CRWSessionEntry* sessionEntry = [_sessionEntries objectAtIndex:index]; | 383     CRWSessionEntry* sessionEntry = [_sessionEntries objectAtIndex:index]; | 
| 383     web::NavigationItem* navigationItem = [sessionEntry navigationItem]; | 384     web::NavigationItem* navigationItem = [sessionEntry navigationItem]; | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 399       previousHost = currentHost; | 400       previousHost = currentHost; | 
| 400     } | 401     } | 
| 401   } | 402   } | 
| 402 | 403 | 
| 403   if ([sectionArray count]) | 404   if ([sectionArray count]) | 
| 404     [partitionedEntries addObject:sectionArray]; | 405     [partitionedEntries addObject:sectionArray]; | 
| 405 | 406 | 
| 406   if (![partitionedEntries count]) | 407   if (![partitionedEntries count]) | 
| 407     partitionedEntries = nil; | 408     partitionedEntries = nil; | 
| 408 | 409 | 
| 409   _partitionedEntries.reset([partitionedEntries retain]); | 410   _partitionedEntries = partitionedEntries; | 
| 410 } | 411 } | 
| 411 | 412 | 
| 412 #pragma mark MDCInkTouchControllerDelegate | 413 #pragma mark MDCInkTouchControllerDelegate | 
| 413 | 414 | 
| 414 - (BOOL)inkTouchController:(MDCInkTouchController*)inkTouchController | 415 - (BOOL)inkTouchController:(MDCInkTouchController*)inkTouchController | 
| 415     shouldProcessInkTouchesAtTouchLocation:(CGPoint)location { | 416     shouldProcessInkTouchesAtTouchLocation:(CGPoint)location { | 
| 416   NSIndexPath* indexPath = | 417   NSIndexPath* indexPath = | 
| 417       [self.collectionView indexPathForItemAtPoint:location]; | 418       [self.collectionView indexPathForItemAtPoint:location]; | 
| 418   TabHistoryCell* cell = base::mac::ObjCCastStrict<TabHistoryCell>( | 419   TabHistoryCell* cell = base::mac::ObjCCastStrict<TabHistoryCell>( | 
| 419       [self.collectionView cellForItemAtIndexPath:indexPath]); | 420       [self.collectionView cellForItemAtIndexPath:indexPath]); | 
| 420   if (!cell) { | 421   if (!cell) { | 
| 421     return NO; | 422     return NO; | 
| 422   } | 423   } | 
| 423 | 424 | 
| 424   // Increase the size of the ink view to cover the collection view from edge | 425   // Increase the size of the ink view to cover the collection view from edge | 
| 425   // to edge. | 426   // to edge. | 
| 426   CGRect inkViewFrame = [cell frame]; | 427   CGRect inkViewFrame = [cell frame]; | 
| 427   inkViewFrame.origin.x = 0; | 428   inkViewFrame.origin.x = 0; | 
| 428   inkViewFrame.size.width = CGRectGetWidth([self.collectionView bounds]); | 429   inkViewFrame.size.width = CGRectGetWidth([self.collectionView bounds]); | 
| 429   [[inkTouchController defaultInkView] setFrame:inkViewFrame]; | 430   [[inkTouchController defaultInkView] setFrame:inkViewFrame]; | 
| 430   return YES; | 431   return YES; | 
| 431 } | 432 } | 
| 432 | 433 | 
| 433 @end | 434 @end | 
| OLD | NEW | 
|---|