OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "chrome/browser/chromeos/status/network_menu_icon.h" | 5 #include "chrome/browser/chromeos/status/network_menu_icon.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <map> | 9 #include <map> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/chromeos/accessibility/accessibility_util.h" | 13 #include "chrome/browser/chromeos/accessibility/accessibility_util.h" |
14 #include "chrome/browser/chromeos/cros/cros_library.h" | 14 #include "chrome/browser/chromeos/cros/cros_library.h" |
15 #include "grit/generated_resources.h" | 15 #include "grit/generated_resources.h" |
16 #include "grit/theme_resources.h" | 16 #include "grit/theme_resources.h" |
17 #include "ui/base/l10n/l10n_util.h" | 17 #include "ui/base/l10n/l10n_util.h" |
18 #include "ui/base/resource/resource_bundle.h" | 18 #include "ui/base/resource/resource_bundle.h" |
19 #include "ui/gfx/canvas.h" | 19 #include "ui/gfx/canvas.h" |
20 #include "ui/gfx/image/image_skia_operations.h" | |
20 #include "ui/gfx/image/image_skia_source.h" | 21 #include "ui/gfx/image/image_skia_source.h" |
21 #include "ui/gfx/skbitmap_operations.h" | |
22 | 22 |
23 using std::max; | 23 using std::max; |
24 using std::min; | 24 using std::min; |
25 | 25 |
26 namespace chromeos { | 26 namespace chromeos { |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
30 // Amount to fade icons while connecting. | 30 // Amount to fade icons while connecting. |
31 const double kConnectingImageAlpha = 0.5; | 31 const double kConnectingImageAlpha = 0.5; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
151 break; | 151 break; |
152 case NETWORK_TECHNOLOGY_UNKNOWN: | 152 case NETWORK_TECHNOLOGY_UNKNOWN: |
153 break; | 153 break; |
154 } | 154 } |
155 if (id == kUnknownBadgeType) | 155 if (id == kUnknownBadgeType) |
156 return NULL; | 156 return NULL; |
157 else | 157 else |
158 return ResourceBundle::GetSharedInstance().GetImageSkiaNamed(id); | 158 return ResourceBundle::GetSharedInstance().GetImageSkiaNamed(id); |
159 } | 159 } |
160 | 160 |
161 const SkBitmap GetEmptyBitmapOfSameSize(const gfx::ImageSkiaRep& reference) { | 161 const SkBitmap GetEmptyBitmap(const gfx::Size pixel_size) { |
162 typedef std::pair<int, int> SizeKey; | 162 typedef std::pair<int, int> SizeKey; |
163 typedef std::map<SizeKey, SkBitmap> SizeBitmapMap; | 163 typedef std::map<SizeKey, SkBitmap> SizeBitmapMap; |
164 static SizeBitmapMap* empty_bitmaps_ = new SizeBitmapMap; | 164 static SizeBitmapMap* empty_bitmaps_ = new SizeBitmapMap; |
165 | 165 |
166 SizeKey key(reference.pixel_width(), reference.pixel_height()); | 166 SizeKey key(pixel_size.width(), pixel_size.height()); |
167 | 167 |
168 SizeBitmapMap::iterator iter = empty_bitmaps_->find(key); | 168 SizeBitmapMap::iterator iter = empty_bitmaps_->find(key); |
169 if (iter != empty_bitmaps_->end()) | 169 if (iter != empty_bitmaps_->end()) |
170 return iter->second; | 170 return iter->second; |
171 | 171 |
172 SkBitmap empty; | 172 SkBitmap empty; |
173 empty.setConfig(SkBitmap::kARGB_8888_Config, key.first, key.second); | 173 empty.setConfig(SkBitmap::kARGB_8888_Config, key.first, key.second); |
174 empty.allocPixels(); | 174 empty.allocPixels(); |
175 empty.eraseARGB(0, 0, 0, 0); | 175 empty.eraseARGB(0, 0, 0, 0); |
176 (*empty_bitmaps_)[key] = empty; | 176 (*empty_bitmaps_)[key] = empty; |
177 return empty; | 177 return empty; |
178 } | 178 } |
179 | 179 |
180 class FadedImageSource : public gfx::ImageSkiaSource { | 180 class EmptyImageSource: public gfx::ImageSkiaSource { |
181 public: | 181 public: |
182 FadedImageSource(const gfx::ImageSkia& source, double alpha) | 182 EmptyImageSource(const gfx::Size& size) |
183 : source_(source), | 183 : size_(size) { |
184 alpha_(alpha) { | |
185 } | 184 } |
186 virtual ~FadedImageSource() {} | |
187 | 185 |
188 virtual gfx::ImageSkiaRep GetImageForScale( | 186 virtual gfx::ImageSkiaRep GetImageForScale( |
189 ui::ScaleFactor scale_factor) OVERRIDE { | 187 ui::ScaleFactor scale_factor) OVERRIDE { |
190 gfx::ImageSkiaRep image_rep = source_.GetRepresentation(scale_factor); | 188 gfx::Size pixel_size = size_.Scale(ui::GetScaleFactorScale(scale_factor)); |
191 const SkBitmap empty_bitmap = GetEmptyBitmapOfSameSize(image_rep); | 189 SkBitmap empty_bitmap = GetEmptyBitmap(pixel_size); |
192 SkBitmap faded_bitmap = SkBitmapOperations::CreateBlendedBitmap( | 190 return gfx::ImageSkiaRep(empty_bitmap, scale_factor); |
193 empty_bitmap, image_rep.sk_bitmap(), alpha_); | |
194 return gfx::ImageSkiaRep(faded_bitmap, image_rep.scale_factor()); | |
195 } | 191 } |
192 private: | |
193 const gfx::Size size_; | |
196 | 194 |
197 private: | 195 DISALLOW_COPY_AND_ASSIGN(EmptyImageSource); |
198 const gfx::ImageSkia source_; | |
199 const float alpha_; | |
200 | |
201 DISALLOW_COPY_AND_ASSIGN(FadedImageSource); | |
202 }; | 196 }; |
203 | 197 |
204 // This defines how we assemble a network icon. | 198 // This defines how we assemble a network icon. |
205 class NetworkIconImageSource : public gfx::ImageSkiaSource { | 199 class NetworkIconImageSource : public gfx::ImageSkiaSource { |
206 public: | 200 public: |
207 NetworkIconImageSource(const gfx::ImageSkia& icon, | 201 NetworkIconImageSource(const gfx::ImageSkia& icon, |
208 const gfx::ImageSkia* top_left_badge, | 202 const gfx::ImageSkia* top_left_badge, |
209 const gfx::ImageSkia* top_right_badge, | 203 const gfx::ImageSkia* top_right_badge, |
210 const gfx::ImageSkia* bottom_left_badge, | 204 const gfx::ImageSkia* bottom_left_badge, |
211 const gfx::ImageSkia* bottom_right_badge) | 205 const gfx::ImageSkia* bottom_right_badge) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
245 private: | 239 private: |
246 const gfx::ImageSkia icon_; | 240 const gfx::ImageSkia icon_; |
247 const gfx::ImageSkia *top_left_badge_; | 241 const gfx::ImageSkia *top_left_badge_; |
248 const gfx::ImageSkia *top_right_badge_; | 242 const gfx::ImageSkia *top_right_badge_; |
249 const gfx::ImageSkia *bottom_left_badge_; | 243 const gfx::ImageSkia *bottom_left_badge_; |
250 const gfx::ImageSkia *bottom_right_badge_; | 244 const gfx::ImageSkia *bottom_right_badge_; |
251 | 245 |
252 DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSource); | 246 DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSource); |
253 }; | 247 }; |
254 | 248 |
255 // This defines how we assemble a network menu icon. | |
256 class NetworkMenuIconSource : public gfx::ImageSkiaSource { | |
257 public: | |
258 NetworkMenuIconSource(NetworkMenuIcon::ImageType type, | |
259 int index, | |
260 NetworkMenuIcon::ResourceColorTheme color) | |
261 : type_(type), | |
262 index_(index), | |
263 color_(color) { | |
264 } | |
265 virtual ~NetworkMenuIconSource() {} | |
266 | |
267 virtual gfx::ImageSkiaRep GetImageForScale( | |
268 ui::ScaleFactor scale_factor) OVERRIDE { | |
269 int width, height; | |
270 gfx::ImageSkia* images; | |
271 if (type_ == NetworkMenuIcon::ARCS) { | |
272 if (index_ >= kNumArcsImages) | |
273 return gfx::ImageSkiaRep(); | |
274 images = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
275 color_ == NetworkMenuIcon::COLOR_DARK ? | |
276 IDR_STATUSBAR_NETWORK_ARCS_DARK : IDR_STATUSBAR_NETWORK_ARCS_LIGHT); | |
277 width = images->width(); | |
278 height = images->height() / kNumArcsImages; | |
279 } else { | |
280 if (index_ >= kNumBarsImages) | |
281 return gfx::ImageSkiaRep(); | |
282 | |
283 images = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
284 color_ == NetworkMenuIcon::COLOR_DARK ? | |
285 IDR_STATUSBAR_NETWORK_BARS_DARK : IDR_STATUSBAR_NETWORK_BARS_LIGHT); | |
286 width = images->width(); | |
287 height = images->height() / kNumBarsImages; | |
288 } | |
289 gfx::ImageSkiaRep image_rep = images->GetRepresentation(scale_factor); | |
290 | |
291 float scale = ui::GetScaleFactorScale(image_rep.scale_factor()); | |
292 height *= scale; | |
293 width *= scale; | |
294 | |
295 SkIRect subset = SkIRect::MakeXYWH(0, index_ * height, width, height); | |
296 | |
297 SkBitmap dst_bitmap; | |
298 image_rep.sk_bitmap().extractSubset(&dst_bitmap, subset); | |
299 return gfx::ImageSkiaRep(dst_bitmap, image_rep.scale_factor()); | |
300 } | |
301 | |
302 gfx::Size size() const { | |
303 // NeworkMenuIcons all have the same size in DIP for arc/bars. | |
304 if (type_ == NetworkMenuIcon::ARCS) { | |
305 gfx::Size size = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
306 IDR_STATUSBAR_NETWORK_ARCS_DARK)->size(); | |
307 return gfx::Size(size.width(), size.height() / kNumArcsImages); | |
308 } else { | |
309 gfx::Size size = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
310 IDR_STATUSBAR_NETWORK_BARS_DARK)->size(); | |
311 return gfx::Size(size.width(), size.height() / kNumBarsImages); | |
312 } | |
313 } | |
314 | |
315 private: | |
316 const NetworkMenuIcon::ImageType type_; | |
317 const int index_; | |
318 const NetworkMenuIcon::ResourceColorTheme color_; | |
319 | |
320 DISALLOW_COPY_AND_ASSIGN(NetworkMenuIconSource); | |
321 }; | |
322 | |
323 gfx::ImageSkia CreateVpnImage() { | 249 gfx::ImageSkia CreateVpnImage() { |
324 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 250 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
325 const gfx::ImageSkia* ethernet_icon = rb.GetImageSkiaNamed(IDR_STATUSBAR_VPN); | 251 const gfx::ImageSkia* ethernet_icon = rb.GetImageSkiaNamed(IDR_STATUSBAR_VPN); |
326 const gfx::ImageSkia* vpn_badge = rb.GetImageSkiaNamed(kVpnBadgeId); | 252 const gfx::ImageSkia* vpn_badge = rb.GetImageSkiaNamed(kVpnBadgeId); |
327 return NetworkMenuIcon::GenerateImageFromComponents( | 253 return NetworkMenuIcon::GenerateImageFromComponents( |
328 *ethernet_icon, NULL, NULL, vpn_badge, NULL); | 254 *ethernet_icon, NULL, NULL, vpn_badge, NULL); |
329 } | 255 } |
330 | 256 |
257 gfx::ImageSkia GetEmptyImage(const gfx::Size& size) { | |
258 return gfx::ImageSkia(new EmptyImageSource(size), size); | |
259 } | |
260 | |
331 } // namespace | 261 } // namespace |
332 | 262 |
333 //////////////////////////////////////////////////////////////////////////////// | 263 //////////////////////////////////////////////////////////////////////////////// |
334 // NetworkIcon | 264 // NetworkIcon |
335 // TODO(stevenjb): Separate class implementation from the definition. | 265 // TODO(stevenjb): Separate class implementation from the definition. |
336 | 266 |
337 // Sets up and generates an ImageSkia for a Network icon. | 267 // Sets up and generates an ImageSkia for a Network icon. |
338 class NetworkIcon { | 268 class NetworkIcon { |
339 public: | 269 public: |
340 // Default constructor is used by the status bar icon (NetworkMenuIcon). | 270 // Default constructor is used by the status bar icon (NetworkMenuIcon). |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
826 icon_->UpdateIcon(network); | 756 icon_->UpdateIcon(network); |
827 // Overlay the VPN badge if connecting to a VPN. | 757 // Overlay the VPN badge if connecting to a VPN. |
828 if (network->type() != TYPE_VPN && cros->virtual_network()) { | 758 if (network->type() != TYPE_VPN && cros->virtual_network()) { |
829 if (cros->virtual_network()->connecting()) { | 759 if (cros->virtual_network()->connecting()) { |
830 const gfx::ImageSkia* vpn_badge = rb.GetImageSkiaNamed(kVpnBadgeId); | 760 const gfx::ImageSkia* vpn_badge = rb.GetImageSkiaNamed(kVpnBadgeId); |
831 const double animation = GetAnimation(); | 761 const double animation = GetAnimation(); |
832 animating = true; | 762 animating = true; |
833 // Even though this is the only place we use vpn_connecting_badge_, | 763 // Even though this is the only place we use vpn_connecting_badge_, |
834 // it is important that this is a member variable since we set a | 764 // it is important that this is a member variable since we set a |
835 // pointer to it and access that pointer in icon_->GenerateImage(). | 765 // pointer to it and access that pointer in icon_->GenerateImage(). |
836 vpn_connecting_badge_ = gfx::ImageSkia( | 766 vpn_connecting_badge_ = gfx::ImageSkiaOperations::CreateBlendedImage( |
837 new FadedImageSource(*vpn_badge, animation), vpn_badge->size()); | 767 GetEmptyImage(vpn_badge->size()), *vpn_badge, animation); |
838 icon_->set_bottom_left_badge(&vpn_connecting_badge_); | 768 icon_->set_bottom_left_badge(&vpn_connecting_badge_); |
839 } | 769 } |
840 } | 770 } |
841 if (!animating) | 771 if (!animating) |
842 animation_connecting_.Stop(); | 772 animation_connecting_.Stop(); |
843 | 773 |
844 // Set the text to display. | 774 // Set the text to display. |
845 if (network->type() == TYPE_ETHERNET) { | 775 if (network->type() == TYPE_ETHERNET) { |
846 if (mode_ == MENU_MODE) { | 776 if (mode_ == MENU_MODE) { |
847 text_ = l10n_util::GetStringFUTF16( | 777 text_ = l10n_util::GetStringFUTF16( |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
903 top_left_badge, | 833 top_left_badge, |
904 top_right_badge, | 834 top_right_badge, |
905 bottom_left_badge, | 835 bottom_left_badge, |
906 bottom_right_badge), | 836 bottom_right_badge), |
907 icon.size()); | 837 icon.size()); |
908 } | 838 } |
909 | 839 |
910 // We blend connecting icons with a black image to generate a faded icon. | 840 // We blend connecting icons with a black image to generate a faded icon. |
911 const gfx::ImageSkia NetworkMenuIcon::GenerateConnectingImage( | 841 const gfx::ImageSkia NetworkMenuIcon::GenerateConnectingImage( |
912 const gfx::ImageSkia& source) { | 842 const gfx::ImageSkia& source) { |
913 return gfx::ImageSkia(new FadedImageSource(source, kConnectingImageAlpha), | 843 return gfx::ImageSkiaOperations::CreateBlendedImage( |
914 source.size()); | 844 GetEmptyImage(source.size()), source, kConnectingImageAlpha); |
915 } | 845 } |
916 | 846 |
917 // Generates and caches an icon image for a network's current state. | 847 // Generates and caches an icon image for a network's current state. |
918 const gfx::ImageSkia NetworkMenuIcon::GetImage(const Network* network, | 848 const gfx::ImageSkia NetworkMenuIcon::GetImage(const Network* network, |
919 ResourceColorTheme color) { | 849 ResourceColorTheme color) { |
920 DCHECK(network); | 850 DCHECK(network); |
921 // Maintain a static (global) icon map. Note: Icons are never destroyed; | 851 // Maintain a static (global) icon map. Note: Icons are never destroyed; |
922 // it is assumed that a finite and reasonable number of network icons will be | 852 // it is assumed that a finite and reasonable number of network icons will be |
923 // created during a session. | 853 // created during a session. |
924 | 854 |
(...skipping 23 matching lines...) Expand all Loading... | |
948 | 878 |
949 // Returns an icon for a disconnected VPN. | 879 // Returns an icon for a disconnected VPN. |
950 const gfx::ImageSkia NetworkMenuIcon::GetVpnImage() { | 880 const gfx::ImageSkia NetworkMenuIcon::GetVpnImage() { |
951 static const gfx::ImageSkia *vpn_image = new gfx::ImageSkia(CreateVpnImage()); | 881 static const gfx::ImageSkia *vpn_image = new gfx::ImageSkia(CreateVpnImage()); |
952 return *vpn_image; | 882 return *vpn_image; |
953 } | 883 } |
954 | 884 |
955 const gfx::ImageSkia NetworkMenuIcon::GetImage(ImageType type, | 885 const gfx::ImageSkia NetworkMenuIcon::GetImage(ImageType type, |
956 int index, | 886 int index, |
957 ResourceColorTheme color) { | 887 ResourceColorTheme color) { |
958 NetworkMenuIconSource* source = new NetworkMenuIconSource(type, index, color); | 888 int width, height; |
sky
2012/07/20 23:21:25
nit: initialize these (and images) just in case.
| |
959 return gfx::ImageSkia(source, source->size()); | 889 gfx::ImageSkia* images; |
890 if (type == NetworkMenuIcon::ARCS) { | |
891 if (index >= kNumArcsImages) | |
892 return gfx::ImageSkia(); | |
893 images = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
894 color == NetworkMenuIcon::COLOR_DARK ? | |
895 IDR_STATUSBAR_NETWORK_ARCS_DARK : IDR_STATUSBAR_NETWORK_ARCS_LIGHT); | |
896 width = images->width(); | |
897 height = images->height() / kNumArcsImages; | |
898 } else { | |
899 if (index >= kNumBarsImages) | |
900 return gfx::ImageSkia(); | |
901 | |
902 images = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
903 color == NetworkMenuIcon::COLOR_DARK ? | |
904 IDR_STATUSBAR_NETWORK_BARS_DARK : IDR_STATUSBAR_NETWORK_BARS_LIGHT); | |
905 width = images->width(); | |
906 height = images->height() / kNumBarsImages; | |
907 } | |
908 return gfx::ImageSkiaOperations::ExtractSubset(*images, | |
909 gfx::Rect(0, index * height, width, height)); | |
960 } | 910 } |
961 | 911 |
962 const gfx::ImageSkia NetworkMenuIcon::GetDisconnectedImage( | 912 const gfx::ImageSkia NetworkMenuIcon::GetDisconnectedImage( |
963 ImageType type, | 913 ImageType type, |
964 ResourceColorTheme color) { | 914 ResourceColorTheme color) { |
965 return GetImage(type, 0, color); | 915 return GetImage(type, 0, color); |
966 } | 916 } |
967 | 917 |
968 const gfx::ImageSkia NetworkMenuIcon::GetConnectedImage(ImageType type, | 918 const gfx::ImageSkia NetworkMenuIcon::GetConnectedImage(ImageType type, |
969 ResourceColorTheme color) { | 919 ResourceColorTheme color) { |
970 return GetImage(type, NumImages(type) - 1, color); | 920 return GetImage(type, NumImages(type) - 1, color); |
971 } | 921 } |
972 | 922 |
973 int NetworkMenuIcon::NumImages(ImageType type) { | 923 int NetworkMenuIcon::NumImages(ImageType type) { |
974 return (type == ARCS) ? kNumArcsImages : kNumBarsImages; | 924 return (type == ARCS) ? kNumArcsImages : kNumBarsImages; |
975 } | 925 } |
976 | 926 |
977 } // chromeos | 927 } // chromeos |
OLD | NEW |