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 "ui/chromeos/network/network_icon.h" | 5 #include "ui/chromeos/network/network_icon.h" |
6 | 6 |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
9 #include "chromeos/network/device_state.h" | 9 #include "chromeos/network/device_state.h" |
10 #include "chromeos/network/network_connection_handler.h" | 10 #include "chromeos/network/network_connection_handler.h" |
11 #include "chromeos/network/network_state.h" | 11 #include "chromeos/network/network_state.h" |
12 #include "chromeos/network/network_state_handler.h" | 12 #include "chromeos/network/network_state_handler.h" |
13 #include "chromeos/network/portal_detector/network_portal_detector.h" | 13 #include "chromeos/network/portal_detector/network_portal_detector.h" |
14 #include "grit/ui_chromeos_resources.h" | 14 #include "grit/ui_chromeos_resources.h" |
15 #include "grit/ui_chromeos_strings.h" | 15 #include "grit/ui_chromeos_strings.h" |
16 #include "third_party/cros_system_api/dbus/service_constants.h" | 16 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 17 #include "third_party/skia/include/core/SkPaint.h" |
| 18 #include "third_party/skia/include/core/SkPath.h" |
17 #include "ui/base/l10n/l10n_util.h" | 19 #include "ui/base/l10n/l10n_util.h" |
18 #include "ui/base/resource/resource_bundle.h" | 20 #include "ui/base/resource/resource_bundle.h" |
19 #include "ui/base/webui/web_ui_util.h" | 21 #include "ui/base/webui/web_ui_util.h" |
20 #include "ui/chromeos/material_design_icon_controller.h" | 22 #include "ui/chromeos/material_design_icon_controller.h" |
21 #include "ui/chromeos/network/network_icon_animation.h" | 23 #include "ui/chromeos/network/network_icon_animation.h" |
22 #include "ui/chromeos/network/network_icon_animation_observer.h" | 24 #include "ui/chromeos/network/network_icon_animation_observer.h" |
23 #include "ui/gfx/canvas.h" | 25 #include "ui/gfx/canvas.h" |
24 #include "ui/gfx/color_palette.h" | 26 #include "ui/gfx/color_palette.h" |
25 #include "ui/gfx/geometry/insets.h" | 27 #include "ui/gfx/geometry/insets.h" |
26 #include "ui/gfx/geometry/rect.h" | 28 #include "ui/gfx/geometry/rect.h" |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 NONE | 174 NONE |
173 }; | 175 }; |
174 | 176 |
175 // Amount to fade icons while connecting. | 177 // Amount to fade icons while connecting. |
176 const double kConnectingImageAlpha = 0.5; | 178 const double kConnectingImageAlpha = 0.5; |
177 | 179 |
178 // Images for strength bars for wired networks. | 180 // Images for strength bars for wired networks. |
179 const int kNumBarsImages = 5; | 181 const int kNumBarsImages = 5; |
180 | 182 |
181 // Images for strength arcs for wireless networks. | 183 // Images for strength arcs for wireless networks. |
| 184 // TODO(estade): consolidate kNumBarsImages and kNumArcsImages; simplify |
| 185 // StrengthIndex(), etc. |
182 const int kNumArcsImages = 5; | 186 const int kNumArcsImages = 5; |
183 | 187 |
184 // Number of discrete images to use for alpha fade animation | 188 // Number of discrete images to use for alpha fade animation |
185 const int kNumFadeImages = 10; | 189 const int kNumFadeImages = 10; |
186 | 190 |
187 SkColor GetBaseColorForIconType(IconType icon_type) { | 191 SkColor GetBaseColorForIconType(IconType icon_type) { |
188 // TODO(estade): use kTrayIconColor and kMenuIconColor. | 192 // TODO(estade): use kTrayIconColor and kMenuIconColor. |
189 return icon_type == ICON_TYPE_TRAY ? SK_ColorWHITE : gfx::kChromeIconGrey; | 193 return icon_type == ICON_TYPE_TRAY ? SK_ColorWHITE : gfx::kChromeIconGrey; |
190 } | 194 } |
191 | 195 |
192 gfx::Size GetSizeForIconType(IconType icon_type) { | 196 gfx::Size GetSizeForIconType(IconType icon_type) { |
193 // TODO(estade): use kTrayIconSize and kMenuIconSize. | 197 // TODO(estade): use kTrayIconSize and kMenuIconSize. |
194 return icon_type == ICON_TYPE_TRAY ? gfx::Size(16, 16) : gfx::Size(20, 20); | 198 return icon_type == ICON_TYPE_TRAY ? gfx::Size(16, 16) : gfx::Size(20, 20); |
195 } | 199 } |
196 | 200 |
| 201 bool IconTypeIsDark(IconType icon_type) { |
| 202 return (icon_type != ICON_TYPE_TRAY); |
| 203 } |
| 204 |
| 205 bool IconTypeHasVPNBadge(IconType icon_type) { |
| 206 return (icon_type != ICON_TYPE_LIST); |
| 207 } |
| 208 |
| 209 int NumImagesForType(ImageType type) { |
| 210 return (type == BARS) ? kNumBarsImages : kNumArcsImages; |
| 211 } |
| 212 |
197 //------------------------------------------------------------------------------ | 213 //------------------------------------------------------------------------------ |
198 // Classes for generating scaled images. | 214 // Classes for generating scaled images. |
199 | 215 |
200 const SkBitmap GetEmptyBitmap(const gfx::Size pixel_size) { | 216 const SkBitmap GetEmptyBitmap(const gfx::Size pixel_size) { |
201 typedef std::pair<int, int> SizeKey; | 217 typedef std::pair<int, int> SizeKey; |
202 typedef std::map<SizeKey, SkBitmap> SizeBitmapMap; | 218 typedef std::map<SizeKey, SkBitmap> SizeBitmapMap; |
203 static SizeBitmapMap* s_empty_bitmaps = new SizeBitmapMap; | 219 static SizeBitmapMap* s_empty_bitmaps = new SizeBitmapMap; |
204 | 220 |
205 SizeKey key(pixel_size.width(), pixel_size.height()); | 221 SizeKey key(pixel_size.width(), pixel_size.height()); |
206 | 222 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 return canvas.ExtractImageRep(); | 281 return canvas.ExtractImageRep(); |
266 } | 282 } |
267 | 283 |
268 private: | 284 private: |
269 const gfx::ImageSkia icon_; | 285 const gfx::ImageSkia icon_; |
270 const Badges badges_; | 286 const Badges badges_; |
271 | 287 |
272 DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSource); | 288 DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSource); |
273 }; | 289 }; |
274 | 290 |
275 // Depicts a given signal strength using arcs (for WiFi connections). | 291 // Depicts a given signal strength using arcs (e.g. for WiFi connections) or |
276 class ArcsImageSource : public gfx::CanvasImageSource { | 292 // bars (e.g. for cell connections). |
| 293 class NetworkIconImageSourceMd : public gfx::CanvasImageSource { |
277 public: | 294 public: |
278 ArcsImageSource(IconType icon_type, float signal_strength) | 295 NetworkIconImageSourceMd(ImageType image_type, |
| 296 IconType icon_type, |
| 297 int signal_strength) |
279 : CanvasImageSource(GetSizeForIconType(icon_type), false), | 298 : CanvasImageSource(GetSizeForIconType(icon_type), false), |
| 299 image_type_(image_type), |
280 icon_type_(icon_type), | 300 icon_type_(icon_type), |
281 signal_strength_(signal_strength) { | 301 signal_strength_(signal_strength) { |
| 302 if (image_type_ == NONE) |
| 303 image_type_ = ARCS; |
| 304 |
282 DCHECK_GE(signal_strength, 0); | 305 DCHECK_GE(signal_strength, 0); |
283 DCHECK_LT(signal_strength, kNumArcsImages); | 306 DCHECK_LT(signal_strength, NumImagesForType(image_type_)); |
284 } | 307 } |
285 ~ArcsImageSource() override {} | 308 ~NetworkIconImageSourceMd() override {} |
286 | 309 |
287 // gfx::CanvasImageSource: | 310 // gfx::CanvasImageSource: |
288 void Draw(gfx::Canvas* canvas) override { | 311 void Draw(gfx::Canvas* canvas) override { |
| 312 if (image_type_ == ARCS) |
| 313 DrawArcs(canvas); |
| 314 else |
| 315 DrawBars(canvas); |
| 316 } |
| 317 bool HasRepresentationAtAllScales() const override { |
| 318 // This image source can handle any scale factor. TODO(estade): investigate |
| 319 // why this doesn't seem to be respected. (Perhaps because we compose |
| 320 // multiple images that don't have representations at all scales?) |
| 321 return true; |
| 322 } |
| 323 |
| 324 private: |
| 325 void DrawArcs(gfx::Canvas* canvas) { |
289 gfx::RectF oval_bounds((gfx::Rect(size()))); | 326 gfx::RectF oval_bounds((gfx::Rect(size()))); |
290 // Padding between top of arc and top of canvas. | |
291 const int kIconInset = 2; | |
292 oval_bounds.Inset(gfx::Insets(kIconInset)); | 327 oval_bounds.Inset(gfx::Insets(kIconInset)); |
293 // Double the width and height. The new midpoint should be the former | 328 // Double the width and height. The new midpoint should be the former |
294 // bottom center. | 329 // bottom center. |
295 oval_bounds.Inset(-oval_bounds.width() / 2, 0, -oval_bounds.width() / 2, | 330 oval_bounds.Inset(-oval_bounds.width() / 2, 0, -oval_bounds.width() / 2, |
296 -oval_bounds.height()); | 331 -oval_bounds.height()); |
297 | 332 |
298 const SkScalar kAngleAboveHorizontal = 51.f; | 333 const SkScalar kAngleAboveHorizontal = 51.f; |
299 const SkScalar kStartAngle = 180.f + kAngleAboveHorizontal; | 334 const SkScalar kStartAngle = 180.f + kAngleAboveHorizontal; |
300 const SkScalar kSweepAngle = 180.f - 2 * kAngleAboveHorizontal; | 335 const SkScalar kSweepAngle = 180.f - 2 * kAngleAboveHorizontal; |
301 | 336 |
302 SkPaint paint; | 337 SkPaint paint; |
303 paint.setAntiAlias(true); | 338 paint.setAntiAlias(true); |
304 paint.setStyle(SkPaint::kFill_Style); | 339 paint.setStyle(SkPaint::kFill_Style); |
305 const SkColor base_color = GetBaseColorForIconType(icon_type_); | 340 const SkColor base_color = GetBaseColorForIconType(icon_type_); |
306 // Background. Skip drawing for full signal. | 341 // Background. Skip drawing for full signal. |
307 if (signal_strength_ != kNumArcsImages - 1) { | 342 if (signal_strength_ != kNumArcsImages - 1) { |
308 // TODO(estade): share this alpha with other things in ash (battery, | 343 paint.setColor(SkColorSetA(base_color, kBgAlpha)); |
309 // etc.). | |
310 paint.setColor(SkColorSetA(base_color, 0x4D)); | |
311 canvas->sk_canvas()->drawArc(gfx::RectFToSkRect(oval_bounds), kStartAngle, | 344 canvas->sk_canvas()->drawArc(gfx::RectFToSkRect(oval_bounds), kStartAngle, |
312 kSweepAngle, true, paint); | 345 kSweepAngle, true, paint); |
313 } | 346 } |
314 // Foreground (signal strength). | 347 // Foreground (signal strength). |
315 if (signal_strength_ != 0) { | 348 if (signal_strength_ != 0) { |
316 paint.setColor(base_color); | 349 paint.setColor(base_color); |
317 // Percent of the height of the background wedge that we draw the | 350 // Percent of the height of the background wedge that we draw the |
318 // foreground wedge, indexed by signal strength. | 351 // foreground wedge, indexed by signal strength. |
319 static const float kWedgeHeightPercentages[] = {0.f, 0.375f, 0.5833f, | 352 static const float kWedgeHeightPercentages[] = {0.f, 0.375f, 0.5833f, |
320 0.75f, 1.f}; | 353 0.75f, 1.f}; |
321 const float wedge_percent = kWedgeHeightPercentages[signal_strength_]; | 354 const float wedge_percent = kWedgeHeightPercentages[signal_strength_]; |
322 oval_bounds.Inset( | 355 oval_bounds.Inset( |
323 gfx::InsetsF((oval_bounds.height() / 2) * (1.f - wedge_percent))); | 356 gfx::InsetsF((oval_bounds.height() / 2) * (1.f - wedge_percent))); |
324 canvas->sk_canvas()->drawArc(gfx::RectFToSkRect(oval_bounds), kStartAngle, | 357 canvas->sk_canvas()->drawArc(gfx::RectFToSkRect(oval_bounds), kStartAngle, |
325 kSweepAngle, true, paint); | 358 kSweepAngle, true, paint); |
326 } | 359 } |
327 } | 360 } |
328 | 361 |
329 private: | 362 void DrawBars(gfx::Canvas* canvas) { |
| 363 // Undo the canvas's device scaling and round values to the nearest whole |
| 364 // number so we can draw on exact pixel boundaries. |
| 365 const float dsf = canvas->UndoDeviceScaleFactor(); |
| 366 auto scale = [dsf](SkScalar dimension) { |
| 367 return std::round(dimension * dsf); |
| 368 }; |
| 369 |
| 370 // Length of short side of an isosceles right triangle, in dip. |
| 371 const SkScalar kFullTriangleSide = |
| 372 SkIntToScalar(size().width()) - kIconInset * 2; |
| 373 |
| 374 auto make_triangle = [scale, kFullTriangleSide](SkScalar side) { |
| 375 SkPath triangle; |
| 376 triangle.moveTo(scale(kIconInset), scale(kIconInset + kFullTriangleSide)); |
| 377 triangle.rLineTo(scale(side), 0); |
| 378 triangle.rLineTo(0, -scale(side)); |
| 379 triangle.close(); |
| 380 return triangle; |
| 381 }; |
| 382 |
| 383 SkPaint paint; |
| 384 paint.setAntiAlias(true); |
| 385 paint.setStyle(SkPaint::kFill_Style); |
| 386 const SkColor base_color = GetBaseColorForIconType(icon_type_); |
| 387 // Background. Skip drawing for full signal. |
| 388 if (signal_strength_ != kNumBarsImages - 1) { |
| 389 paint.setColor(SkColorSetA(base_color, kBgAlpha)); |
| 390 canvas->DrawPath(make_triangle(kFullTriangleSide), paint); |
| 391 } |
| 392 // Foreground (signal strength). |
| 393 if (signal_strength_ != 0) { |
| 394 paint.setColor(base_color); |
| 395 // As a percentage of the bg triangle, the length of one of the short |
| 396 // sides of the fg triangle, indexed by signal strength. |
| 397 static const float kTriangleSidePercents[] = {0.f, 0.5f, 0.625f, 0.75f, |
| 398 1.f}; |
| 399 canvas->DrawPath(make_triangle(kTriangleSidePercents[signal_strength_] * |
| 400 kFullTriangleSide), |
| 401 paint); |
| 402 } |
| 403 } |
| 404 |
| 405 ImageType image_type_; |
330 IconType icon_type_; | 406 IconType icon_type_; |
331 // On a scale of 0 to kNumArcsImages - 1, how connected we are. | 407 |
| 408 // On a scale of 0 to kNum{Arcs,Bars}Images - 1, how connected we are. |
332 int signal_strength_; | 409 int signal_strength_; |
333 | 410 |
334 DISALLOW_COPY_AND_ASSIGN(ArcsImageSource); | 411 // Padding between outside of icon and edge of the canvas, in dp. This value |
| 412 // stays the same regardless of the canvas size (which depends on |
| 413 // |icon_type_|). |
| 414 static constexpr int kIconInset = 2; |
| 415 |
| 416 // TODO(estade): share this alpha with other things in ash (battery, etc.). |
| 417 // See crbug.com/623987 and crbug.com/632827 |
| 418 static constexpr int kBgAlpha = 0x4D; |
| 419 |
| 420 DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSourceMd); |
335 }; | 421 }; |
336 | 422 |
337 //------------------------------------------------------------------------------ | 423 //------------------------------------------------------------------------------ |
338 // Utilities for extracting icon images. | 424 // Utilities for extracting icon images. |
339 | 425 |
340 bool IconTypeIsDark(IconType icon_type) { | |
341 return (icon_type != ICON_TYPE_TRAY); | |
342 } | |
343 | |
344 bool IconTypeHasVPNBadge(IconType icon_type) { | |
345 return (icon_type != ICON_TYPE_LIST); | |
346 } | |
347 | |
348 int NumImagesForType(ImageType type) { | |
349 return (type == BARS) ? kNumBarsImages : kNumArcsImages; | |
350 } | |
351 | |
352 gfx::ImageSkia* BaseImageForType(ImageType image_type, IconType icon_type) { | 426 gfx::ImageSkia* BaseImageForType(ImageType image_type, IconType icon_type) { |
353 gfx::ImageSkia* image; | 427 gfx::ImageSkia* image; |
354 if (image_type == BARS) { | 428 if (image_type == BARS) { |
355 image = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 429 image = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
356 IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_BARS_DARK | 430 IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_BARS_DARK |
357 : IDR_AURA_UBER_TRAY_NETWORK_BARS_LIGHT); | 431 : IDR_AURA_UBER_TRAY_NETWORK_BARS_LIGHT); |
358 } else { | 432 } else { |
359 image = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 433 image = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
360 IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_ARCS_DARK | 434 IconTypeIsDark(icon_type) ? IDR_AURA_UBER_TRAY_NETWORK_ARCS_DARK |
361 : IDR_AURA_UBER_TRAY_NETWORK_ARCS_LIGHT); | 435 : IDR_AURA_UBER_TRAY_NETWORK_ARCS_LIGHT); |
362 } | 436 } |
363 return image; | 437 return image; |
364 } | 438 } |
365 | 439 |
366 ImageType ImageTypeForNetworkType(const std::string& type) { | 440 ImageType ImageTypeForNetworkType(const std::string& type) { |
367 if (type == shill::kTypeWifi) | 441 if (type == shill::kTypeWifi) |
368 return ARCS; | 442 return ARCS; |
369 else if (type == shill::kTypeCellular || type == shill::kTypeWimax) | 443 else if (type == shill::kTypeCellular || type == shill::kTypeWimax) |
370 return BARS; | 444 return BARS; |
371 return NONE; | 445 return NONE; |
372 } | 446 } |
373 | 447 |
374 gfx::ImageSkia GetImageForIndex(ImageType image_type, | 448 gfx::ImageSkia GetImageForIndex(ImageType image_type, |
375 IconType icon_type, | 449 IconType icon_type, |
376 int index) { | 450 int index) { |
377 if (md_icon_controller::UseMaterialDesignNetworkIcons() && | 451 if (md_icon_controller::UseMaterialDesignNetworkIcons()) { |
378 image_type == ARCS) { | 452 gfx::CanvasImageSource* source = |
379 ArcsImageSource* source = new ArcsImageSource(icon_type, index); | 453 new NetworkIconImageSourceMd(image_type, icon_type, index); |
380 return gfx::ImageSkia(source, source->size()); | 454 return gfx::ImageSkia(source, source->size()); |
381 } | 455 } |
382 | 456 |
383 int num_images = NumImagesForType(image_type); | 457 int num_images = NumImagesForType(image_type); |
384 if (index < 0 || index >= num_images) | 458 if (index < 0 || index >= num_images) |
385 return gfx::ImageSkia(); | 459 return gfx::ImageSkia(); |
386 gfx::ImageSkia* images = BaseImageForType(image_type, icon_type); | 460 gfx::ImageSkia* images = BaseImageForType(image_type, icon_type); |
387 int width = images->width(); | 461 int width = images->width(); |
388 int height = images->height() / num_images; | 462 int height = images->height() / num_images; |
389 return gfx::ImageSkiaOperations::ExtractSubset(*images, | 463 return gfx::ImageSkiaOperations::ExtractSubset(*images, |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 iter != networks.end(); ++iter) { | 1054 iter != networks.end(); ++iter) { |
981 network_paths.insert((*iter)->path()); | 1055 network_paths.insert((*iter)->path()); |
982 } | 1056 } |
983 PurgeIconMap(ICON_TYPE_TRAY, network_paths); | 1057 PurgeIconMap(ICON_TYPE_TRAY, network_paths); |
984 PurgeIconMap(ICON_TYPE_DEFAULT_VIEW, network_paths); | 1058 PurgeIconMap(ICON_TYPE_DEFAULT_VIEW, network_paths); |
985 PurgeIconMap(ICON_TYPE_LIST, network_paths); | 1059 PurgeIconMap(ICON_TYPE_LIST, network_paths); |
986 } | 1060 } |
987 | 1061 |
988 } // namespace network_icon | 1062 } // namespace network_icon |
989 } // namespace ui | 1063 } // namespace ui |
OLD | NEW |