Index: ui/chromeos/network/network_icon.cc |
diff --git a/ui/chromeos/network/network_icon.cc b/ui/chromeos/network/network_icon.cc |
index 6f1926244f92c39bb3669fc9e0244dfc03998219..5ebc8633ea18f306905cd08db710475fca4c7bf4 100644 |
--- a/ui/chromeos/network/network_icon.cc |
+++ b/ui/chromeos/network/network_icon.cc |
@@ -14,6 +14,8 @@ |
#include "grit/ui_chromeos_resources.h" |
#include "grit/ui_chromeos_strings.h" |
#include "third_party/cros_system_api/dbus/service_constants.h" |
+#include "third_party/skia/include/core/SkPaint.h" |
+#include "third_party/skia/include/core/SkPath.h" |
#include "ui/base/l10n/l10n_util.h" |
#include "ui/base/resource/resource_bundle.h" |
#include "ui/base/webui/web_ui_util.h" |
@@ -272,23 +274,37 @@ class NetworkIconImageSource : public gfx::ImageSkiaSource { |
DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSource); |
}; |
-// Depicts a given signal strength using arcs (for WiFi connections). |
-class ArcsImageSource : public gfx::CanvasImageSource { |
+// Depicts a given signal strength using arcs (e.g. for WiFi connections) or |
+// bars (e.g. for cell connections). |
+class NetworkIconImageSourceMd : public gfx::CanvasImageSource { |
public: |
- ArcsImageSource(IconType icon_type, float signal_strength) |
+ NetworkIconImageSourceMd(ImageType image_type, |
+ IconType icon_type, |
+ int signal_strength) |
: CanvasImageSource(GetSizeForIconType(icon_type), false), |
+ image_type_(image_type), |
icon_type_(icon_type), |
signal_strength_(signal_strength) { |
+ if (image_type_ == NONE) |
+ image_type_ = ARCS; |
+ |
DCHECK_GE(signal_strength, 0); |
- DCHECK_LT(signal_strength, kNumArcsImages); |
+ DCHECK_LT(signal_strength, |
+ image_type_ == ARCS ? kNumArcsImages : kNumBarsImages); |
tdanderson
2016/07/29 21:43:29
Maybe consolidate these two constants into kNumNet
stevenjb
2016/07/29 21:47:05
FWIW, the number of arcs/bars images used to diffe
Evan Stade
2016/07/29 22:25:18
It looks like a lot of simplification is possible
|
} |
- ~ArcsImageSource() override {} |
+ ~NetworkIconImageSourceMd() override {} |
// gfx::CanvasImageSource: |
void Draw(gfx::Canvas* canvas) override { |
+ if (image_type_ == ARCS) |
+ DrawArcs(canvas); |
+ else |
+ DrawBars(canvas); |
+ } |
+ |
+ private: |
+ void DrawArcs(gfx::Canvas* canvas) { |
gfx::RectF oval_bounds((gfx::Rect(size()))); |
- // Padding between top of arc and top of canvas. |
- const int kIconInset = 2; |
oval_bounds.Inset(gfx::Insets(kIconInset)); |
// Double the width and height. The new midpoint should be the former |
// bottom center. |
@@ -305,9 +321,7 @@ class ArcsImageSource : public gfx::CanvasImageSource { |
const SkColor base_color = GetBaseColorForIconType(icon_type_); |
// Background. Skip drawing for full signal. |
if (signal_strength_ != kNumArcsImages - 1) { |
- // TODO(estade): share this alpha with other things in ash (battery, |
- // etc.). |
- paint.setColor(SkColorSetA(base_color, 0x4D)); |
+ paint.setColor(SkColorSetA(base_color, kBgAlpha)); |
canvas->sk_canvas()->drawArc(gfx::RectFToSkRect(oval_bounds), kStartAngle, |
kSweepAngle, true, paint); |
} |
@@ -326,12 +340,62 @@ class ArcsImageSource : public gfx::CanvasImageSource { |
} |
} |
- private: |
+ void DrawBars(gfx::Canvas* canvas) { |
+ // Undo the canvas's device scaling and round values to the nearest whole |
+ // number so we can draw on exact pixel boundaries. |
+ const float dsf = canvas->UndoDeviceScaleFactor(); |
+ auto scale = [dsf](int dimension) { return std::round(dimension * dsf); }; |
+ |
+ // Length of short side of an isosceles right triangle. |
+ const SkScalar kFullTriangleSide = |
+ SkIntToScalar(size().width() - kIconInset * 2); |
+ |
+ auto make_triangle = [scale, kFullTriangleSide](SkScalar side) { |
+ SkPath triangle; |
+ triangle.moveTo(scale(kIconInset), scale(kIconInset + kFullTriangleSide)); |
+ triangle.rLineTo(scale(side), 0); |
+ triangle.rLineTo(0, -scale(side)); |
+ triangle.close(); |
+ return triangle; |
+ }; |
+ |
+ SkPaint paint; |
+ paint.setAntiAlias(true); |
+ paint.setStyle(SkPaint::kFill_Style); |
+ const SkColor base_color = GetBaseColorForIconType(icon_type_); |
+ // Background. Skip drawing for full signal. |
+ if (signal_strength_ != kNumBarsImages - 1) { |
+ paint.setColor(SkColorSetA(base_color, kBgAlpha)); |
+ canvas->DrawPath(make_triangle(kFullTriangleSide), paint); |
+ } |
+ // Foreground (signal strength). |
+ if (signal_strength_ != 0) { |
+ paint.setColor(base_color); |
+ // As a percentage of the bg triangle, the length of one of the short |
+ // sides of the fg triangle, indexed by signal strength. |
+ static const float kTriangleSidePercents[] = {0.f, 0.5f, 0.625f, 0.75f, |
+ 1.f}; |
+ canvas->DrawPath(make_triangle(kTriangleSidePercents[signal_strength_] * |
+ kFullTriangleSide), |
+ paint); |
+ } |
+ } |
+ |
+ ImageType image_type_; |
IconType icon_type_; |
- // On a scale of 0 to kNumArcsImages - 1, how connected we are. |
+ |
+ // On a scale of 0 to kNum{Arcs,Bars}Images - 1, how connected we are. |
int signal_strength_; |
- DISALLOW_COPY_AND_ASSIGN(ArcsImageSource); |
+ // Padding between outside of icon and edge of the canvas, in dp. This value |
+ // stays the same regardless of the canvas size (which depends on |
+ // |icon_type_|). |
+ static constexpr int kIconInset = 2; |
+ |
+ // TODO(estade): share this alpha with other things in ash (battery, etc.). |
tdanderson
2016/07/29 21:43:29
Consider referencing crbug.com/623987
Evan Stade
2016/07/29 22:25:18
Done.
|
+ static constexpr int kBgAlpha = 0x4D; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(NetworkIconImageSourceMd); |
}; |
//------------------------------------------------------------------------------ |
@@ -374,9 +438,9 @@ ImageType ImageTypeForNetworkType(const std::string& type) { |
gfx::ImageSkia GetImageForIndex(ImageType image_type, |
IconType icon_type, |
int index) { |
- if (md_icon_controller::UseMaterialDesignNetworkIcons() && |
- image_type == ARCS) { |
- ArcsImageSource* source = new ArcsImageSource(icon_type, index); |
+ if (md_icon_controller::UseMaterialDesignNetworkIcons()) { |
+ gfx::CanvasImageSource* source = |
+ new NetworkIconImageSourceMd(image_type, icon_type, index); |
return gfx::ImageSkia(source, source->size()); |
} |