| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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/ntp/most_visited_cell.h" | 5 #import "ios/chrome/browser/ui/ntp/most_visited_cell.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #import "base/ios/weak_nsobject.h" | |
| 10 #include "base/mac/bind_objc_block.h" | 9 #include "base/mac/bind_objc_block.h" |
| 11 #import "base/mac/scoped_nsobject.h" | |
| 12 #include "base/memory/ref_counted_memory.h" | 10 #include "base/memory/ref_counted_memory.h" |
| 13 #include "base/strings/sys_string_conversions.h" | 11 #include "base/strings/sys_string_conversions.h" |
| 14 #include "base/task/cancelable_task_tracker.h" | 12 #include "base/task/cancelable_task_tracker.h" |
| 15 #include "components/favicon/core/fallback_url_util.h" | 13 #include "components/favicon/core/fallback_url_util.h" |
| 16 #include "components/favicon/core/large_icon_service.h" | 14 #include "components/favicon/core/large_icon_service.h" |
| 17 #include "components/favicon_base/fallback_icon_style.h" | 15 #include "components/favicon_base/fallback_icon_style.h" |
| 18 #include "components/favicon_base/favicon_types.h" | 16 #include "components/favicon_base/favicon_types.h" |
| 19 #include "components/history/core/browser/top_sites.h" | 17 #include "components/history/core/browser/top_sites.h" |
| 20 #include "components/suggestions/suggestions_service.h" | 18 #include "components/suggestions/suggestions_service.h" |
| 21 #import "ios/chrome/browser/favicon/favicon_loader.h" | 19 #import "ios/chrome/browser/favicon/favicon_loader.h" |
| 22 #include "ios/chrome/browser/favicon/favicon_service_factory.h" | 20 #include "ios/chrome/browser/favicon/favicon_service_factory.h" |
| 23 #include "ios/chrome/browser/favicon/large_icon_cache.h" | 21 #include "ios/chrome/browser/favicon/large_icon_cache.h" |
| 24 #include "ios/chrome/browser/history/top_sites_factory.h" | 22 #include "ios/chrome/browser/history/top_sites_factory.h" |
| 25 #include "ios/chrome/browser/suggestions/suggestions_service_factory.h" | 23 #include "ios/chrome/browser/suggestions/suggestions_service_factory.h" |
| 26 #import "ios/chrome/browser/ui/ntp/google_landing_data_source.h" | 24 #import "ios/chrome/browser/ui/ntp/google_landing_data_source.h" |
| 27 #import "ios/chrome/browser/ui/uikit_ui_util.h" | 25 #import "ios/chrome/browser/ui/uikit_ui_util.h" |
| 28 #import "ios/third_party/material_components_ios/src/components/Palettes/src/Mat
erialPalettes.h" | 26 #import "ios/third_party/material_components_ios/src/components/Palettes/src/Mat
erialPalettes.h" |
| 29 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" | 27 #import "ios/third_party/material_components_ios/src/components/Typography/src/M
aterialTypography.h" |
| 30 #include "skia/ext/skia_utils_ios.h" | 28 #include "skia/ext/skia_utils_ios.h" |
| 31 | 29 |
| 30 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 31 #error "This file requires ARC support." |
| 32 #endif |
| 33 |
| 32 const CGFloat kFaviconSize = 48; | 34 const CGFloat kFaviconSize = 48; |
| 33 const CGFloat kFaviconMinSize = 32; | 35 const CGFloat kFaviconMinSize = 32; |
| 34 const CGFloat kImageViewBackgroundColor = 0.941; | 36 const CGFloat kImageViewBackgroundColor = 0.941; |
| 35 const CGFloat kImageViewCornerRadius = 3; | 37 const CGFloat kImageViewCornerRadius = 3; |
| 36 const NSInteger kLabelNumLines = 2; | 38 const NSInteger kLabelNumLines = 2; |
| 37 const CGFloat kLabelTextColor = 0.314; | 39 const CGFloat kLabelTextColor = 0.314; |
| 38 const CGFloat kMaximumWidth = 73; | 40 const CGFloat kMaximumWidth = 73; |
| 39 const CGFloat kMaximumHeight = 100; | 41 const CGFloat kMaximumHeight = 100; |
| 40 | 42 |
| 41 @interface MostVisitedCell () { | 43 @interface MostVisitedCell () { |
| 42 // Backs property with the same name. | 44 // Backs property with the same name. |
| 43 GURL _URL; | 45 GURL _URL; |
| 44 // Weak reference to the relevant GoogleLandingDataSource. | 46 // Weak reference to the relevant GoogleLandingDataSource. |
| 45 base::WeakNSProtocol<id<GoogleLandingDataSource>> _dataSource; | 47 __weak id<GoogleLandingDataSource> _dataSource; |
| 46 // Backs property with the same name. | 48 // Backs property with the same name. |
| 47 ntp_tiles::TileVisualType _tileType; | 49 ntp_tiles::TileVisualType _tileType; |
| 48 | 50 |
| 49 base::scoped_nsobject<UILabel> _label; | 51 UILabel* _label; |
| 50 base::scoped_nsobject<UILabel> _noIconLabel; | 52 UILabel* _noIconLabel; |
| 51 base::scoped_nsobject<UIImageView> _imageView; | 53 UIImageView* _imageView; |
| 52 // Used to cancel tasks for the LargeIconService. | 54 // Used to cancel tasks for the LargeIconService. |
| 53 base::CancelableTaskTracker _cancelable_task_tracker; | 55 base::CancelableTaskTracker _cancelable_task_tracker; |
| 54 } | 56 } |
| 55 // Set the background color and center the first letter of the site title (or | 57 // Set the background color and center the first letter of the site title (or |
| 56 // domain if the title is a url). | 58 // domain if the title is a url). |
| 57 - (void)updateIconLabelWithColor:(UIColor*)textColor | 59 - (void)updateIconLabelWithColor:(UIColor*)textColor |
| 58 backgroundColor:(UIColor*)backgroundColor | 60 backgroundColor:(UIColor*)backgroundColor |
| 59 isDefaultBackgroundColor:(BOOL)isDefaultBackgroundColor; | 61 isDefaultBackgroundColor:(BOOL)isDefaultBackgroundColor; |
| 60 // Set icon of top site. | 62 // Set icon of top site. |
| 61 - (void)setImage:(UIImage*)image; | 63 - (void)setImage:(UIImage*)image; |
| 62 @end | 64 @end |
| 63 | 65 |
| 64 @implementation MostVisitedCell | 66 @implementation MostVisitedCell |
| 65 | 67 |
| 66 @synthesize URL = _URL; | 68 @synthesize URL = _URL; |
| 67 @synthesize tileType = _tileType; | 69 @synthesize tileType = _tileType; |
| 68 | 70 |
| 69 - (instancetype)initWithFrame:(CGRect)frame { | 71 - (instancetype)initWithFrame:(CGRect)frame { |
| 70 self = [super initWithFrame:frame]; | 72 self = [super initWithFrame:frame]; |
| 71 if (!self) { | 73 if (!self) { |
| 72 return nil; | 74 return nil; |
| 73 } | 75 } |
| 74 _label.reset([[UILabel alloc] initWithFrame:CGRectZero]); | 76 _label = [[UILabel alloc] initWithFrame:CGRectZero]; |
| 75 [_label setTextColor:[UIColor colorWithWhite:kLabelTextColor alpha:1.0]]; | 77 [_label setTextColor:[UIColor colorWithWhite:kLabelTextColor alpha:1.0]]; |
| 76 [_label setBackgroundColor:[UIColor clearColor]]; | 78 [_label setBackgroundColor:[UIColor clearColor]]; |
| 77 [_label setFont:[MDCTypography captionFont]]; | 79 [_label setFont:[MDCTypography captionFont]]; |
| 78 [_label setTextAlignment:NSTextAlignmentCenter]; | 80 [_label setTextAlignment:NSTextAlignmentCenter]; |
| 79 CGSize maxSize = [self.class maximumSize]; | 81 CGSize maxSize = [self.class maximumSize]; |
| 80 [_label setPreferredMaxLayoutWidth:maxSize.width]; | 82 [_label setPreferredMaxLayoutWidth:maxSize.width]; |
| 81 [_label setNumberOfLines:kLabelNumLines]; | 83 [_label setNumberOfLines:kLabelNumLines]; |
| 82 | 84 |
| 83 _noIconLabel.reset([[UILabel alloc] initWithFrame:CGRectZero]); | 85 _noIconLabel = [[UILabel alloc] initWithFrame:CGRectZero]; |
| 84 [_noIconLabel setBackgroundColor:[UIColor clearColor]]; | 86 [_noIconLabel setBackgroundColor:[UIColor clearColor]]; |
| 85 [_noIconLabel setFont:[MDCTypography headlineFont]]; | 87 [_noIconLabel setFont:[MDCTypography headlineFont]]; |
| 86 [_noIconLabel setTextAlignment:NSTextAlignmentCenter]; | 88 [_noIconLabel setTextAlignment:NSTextAlignmentCenter]; |
| 87 | 89 |
| 88 _imageView.reset([[UIImageView alloc] initWithFrame:CGRectZero]); | 90 _imageView = [[UIImageView alloc] initWithFrame:CGRectZero]; |
| 89 [_imageView layer].cornerRadius = kImageViewCornerRadius; | 91 [_imageView layer].cornerRadius = kImageViewCornerRadius; |
| 90 [_imageView setClipsToBounds:YES]; | 92 [_imageView setClipsToBounds:YES]; |
| 91 [self addSubview:_imageView]; | 93 [self addSubview:_imageView]; |
| 92 [self addSubview:_label]; | 94 [self addSubview:_label]; |
| 93 [self addSubview:_noIconLabel]; | 95 [self addSubview:_noIconLabel]; |
| 94 | 96 |
| 95 [_noIconLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; | 97 [_noIconLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 96 [_imageView setTranslatesAutoresizingMaskIntoConstraints:NO]; | 98 [_imageView setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 97 [_label setTranslatesAutoresizingMaskIntoConstraints:NO]; | 99 [_label setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| 98 | 100 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 [self setUserInteractionEnabled:YES]; | 141 [self setUserInteractionEnabled:YES]; |
| 140 } | 142 } |
| 141 | 143 |
| 142 - (void)showPlaceholder { | 144 - (void)showPlaceholder { |
| 143 [_imageView setBackgroundColor:[[MDCPalette greyPalette] tint50]]; | 145 [_imageView setBackgroundColor:[[MDCPalette greyPalette] tint50]]; |
| 144 } | 146 } |
| 145 | 147 |
| 146 - (void)setupWithURL:(GURL)URL | 148 - (void)setupWithURL:(GURL)URL |
| 147 title:(NSString*)title | 149 title:(NSString*)title |
| 148 dataSource:(id<GoogleLandingDataSource>)dataSource { | 150 dataSource:(id<GoogleLandingDataSource>)dataSource { |
| 149 _dataSource.reset(dataSource); | 151 _dataSource = dataSource; |
| 150 _tileType = ntp_tiles::TileVisualType::NONE; | 152 _tileType = ntp_tiles::TileVisualType::NONE; |
| 151 [self setText:title]; | 153 [self setText:title]; |
| 152 [self setURL:URL]; | 154 [self setURL:URL]; |
| 153 base::WeakNSObject<MostVisitedCell> weakSelf(self); | 155 __weak MostVisitedCell* weakSelf = self; |
| 154 | 156 |
| 155 void (^faviconBlock)(const favicon_base::LargeIconResult&) = | 157 void (^faviconBlock)(const favicon_base::LargeIconResult&) = |
| 156 ^(const favicon_base::LargeIconResult& result) { | 158 ^(const favicon_base::LargeIconResult& result) { |
| 157 base::scoped_nsobject<MostVisitedCell> strongSelf([weakSelf retain]); | 159 MostVisitedCell* strongSelf = weakSelf; |
| 158 if (!strongSelf) | 160 if (!strongSelf) |
| 159 return; | 161 return; |
| 160 | 162 |
| 161 if (URL == [strongSelf URL]) { // Tile has not been reused. | 163 if (URL == [strongSelf URL]) { // Tile has not been reused. |
| 162 if (result.bitmap.is_valid()) { | 164 if (result.bitmap.is_valid()) { |
| 163 scoped_refptr<base::RefCountedMemory> data = | 165 scoped_refptr<base::RefCountedMemory> data = |
| 164 result.bitmap.bitmap_data.get(); | 166 result.bitmap.bitmap_data.get(); |
| 165 UIImage* favicon = | 167 UIImage* favicon = |
| 166 [UIImage imageWithData:[NSData dataWithBytes:data->front() | 168 [UIImage imageWithData:[NSData dataWithBytes:data->front() |
| 167 length:data->size()] | 169 length:data->size()] |
| 168 scale:[UIScreen mainScreen].scale]; | 170 scale:[UIScreen mainScreen].scale]; |
| 169 [strongSelf setImage:favicon]; | 171 [strongSelf setImage:favicon]; |
| 170 } else if (result.fallback_icon_style) { | 172 } else if (result.fallback_icon_style) { |
| 171 UIColor* backgroundColor = skia::UIColorFromSkColor( | 173 UIColor* backgroundColor = skia::UIColorFromSkColor( |
| 172 result.fallback_icon_style->background_color); | 174 result.fallback_icon_style->background_color); |
| 173 UIColor* textColor = skia::UIColorFromSkColor( | 175 UIColor* textColor = skia::UIColorFromSkColor( |
| 174 result.fallback_icon_style->text_color); | 176 result.fallback_icon_style->text_color); |
| 175 [strongSelf updateIconLabelWithColor:textColor | 177 [strongSelf updateIconLabelWithColor:textColor |
| 176 backgroundColor:backgroundColor | 178 backgroundColor:backgroundColor |
| 177 isDefaultBackgroundColor:result.fallback_icon_style-> | 179 isDefaultBackgroundColor:result.fallback_icon_style-> |
| 178 is_default_background_color]; | 180 is_default_background_color]; |
| 179 } | 181 } |
| 180 } | 182 } |
| 181 | 183 |
| 182 if (result.bitmap.is_valid() || result.fallback_icon_style) { | 184 if (result.bitmap.is_valid() || result.fallback_icon_style) { |
| 183 LargeIconCache* largeIconCache = | 185 LargeIconCache* largeIconCache = |
| 184 [strongSelf.get()->_dataSource largeIconCache]; | 186 [strongSelf->_dataSource largeIconCache]; |
| 185 if (largeIconCache) | 187 if (largeIconCache) |
| 186 largeIconCache->SetCachedResult(URL, result); | 188 largeIconCache->SetCachedResult(URL, result); |
| 187 } | 189 } |
| 188 }; | 190 }; |
| 189 | 191 |
| 190 LargeIconCache* cache = [_dataSource largeIconCache]; | 192 LargeIconCache* cache = [_dataSource largeIconCache]; |
| 191 std::unique_ptr<favicon_base::LargeIconResult> cached_result = | 193 std::unique_ptr<favicon_base::LargeIconResult> cached_result = |
| 192 cache->GetCachedResult(URL); | 194 cache->GetCachedResult(URL); |
| 193 if (cached_result) { | 195 if (cached_result) { |
| 194 faviconBlock(*cached_result); | 196 faviconBlock(*cached_result); |
| 195 } | 197 } |
| 196 | 198 |
| 197 // Always call LargeIconService in case the favicon was updated. | 199 // Always call LargeIconService in case the favicon was updated. |
| 198 favicon::LargeIconService* large_icon_service = | 200 favicon::LargeIconService* large_icon_service = |
| 199 [_dataSource largeIconService]; | 201 [_dataSource largeIconService]; |
| 200 CGFloat faviconSize = [UIScreen mainScreen].scale * kFaviconSize; | 202 CGFloat faviconSize = [UIScreen mainScreen].scale * kFaviconSize; |
| 201 CGFloat faviconMinSize = [UIScreen mainScreen].scale * kFaviconMinSize; | 203 CGFloat faviconMinSize = [UIScreen mainScreen].scale * kFaviconMinSize; |
| 202 large_icon_service->GetLargeIconOrFallbackStyle( | 204 large_icon_service->GetLargeIconOrFallbackStyle( |
| 203 URL, faviconMinSize, faviconSize, base::BindBlock(faviconBlock), | 205 URL, faviconMinSize, faviconSize, base::BindBlockArc(faviconBlock), |
| 204 &_cancelable_task_tracker); | 206 &_cancelable_task_tracker); |
| 205 } | 207 } |
| 206 | 208 |
| 207 - (void)removePlaceholderImage { | 209 - (void)removePlaceholderImage { |
| 208 [_imageView setBackgroundColor:nil]; | 210 [_imageView setBackgroundColor:nil]; |
| 209 [self setUserInteractionEnabled:NO]; | 211 [self setUserInteractionEnabled:NO]; |
| 210 } | 212 } |
| 211 | 213 |
| 212 #pragma mark - Class methods | 214 #pragma mark - Class methods |
| 213 | 215 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 230 } | 232 } |
| 231 | 233 |
| 232 - (void)setImage:(UIImage*)image { | 234 - (void)setImage:(UIImage*)image { |
| 233 [_imageView setBackgroundColor:nil]; | 235 [_imageView setBackgroundColor:nil]; |
| 234 [_noIconLabel setText:nil]; | 236 [_noIconLabel setText:nil]; |
| 235 [_imageView setImage:image]; | 237 [_imageView setImage:image]; |
| 236 _tileType = ntp_tiles::TileVisualType::ICON_REAL; | 238 _tileType = ntp_tiles::TileVisualType::ICON_REAL; |
| 237 } | 239 } |
| 238 | 240 |
| 239 @end | 241 @end |
| OLD | NEW |