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 |