| 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 |