Chromium Code Reviews| Index: ash/system/chromeos/power/power_status.cc |
| diff --git a/ash/system/chromeos/power/power_status.cc b/ash/system/chromeos/power/power_status.cc |
| index 5b2a0ade4366799b3f475cb3e79e1b5b495dcdc8..ad47ff9960bda4cae6ba44c4ceb29ea70d4aa5e3 100644 |
| --- a/ash/system/chromeos/power/power_status.cc |
| +++ b/ash/system/chromeos/power/power_status.cc |
| @@ -19,9 +19,12 @@ |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/l10n/time_format.h" |
| #include "ui/base/resource/resource_bundle.h" |
| +#include "ui/gfx/canvas.h" |
| #include "ui/gfx/geometry/rect.h" |
| #include "ui/gfx/image/image.h" |
| #include "ui/gfx/image/image_skia_operations.h" |
| +#include "ui/gfx/paint_vector_icon.h" |
| +#include "ui/gfx/vector_icons_public.h" |
| namespace ash { |
| namespace { |
| @@ -95,6 +98,23 @@ int PowerSourceToMessageID( |
| return 0; |
| } |
| +gfx::VectorIconId VectorIconIdForIconBadge(PowerStatus::IconBadge icon_badge) { |
| + // TODO(tdanderson): Create vector icons for remaining types. See |
| + // crbug.com/617298. |
| + switch (icon_badge) { |
| + case PowerStatus::ICON_BADGE_NONE: |
| + return gfx::VectorIconId::VECTOR_ICON_NONE; |
| + case PowerStatus::ICON_BADGE_ALERT: |
| + case PowerStatus::ICON_BADGE_X: |
| + case PowerStatus::ICON_BADGE_BOLT: |
| + case PowerStatus::ICON_BADGE_QUESTION: |
| + case PowerStatus::ICON_BADGE_UNRELIABLE: |
| + return gfx::VectorIconId::SYSTEM_TRAY_BATTERY_BOLT_TEST; |
| + } |
| + NOTREACHED(); |
| + return gfx::VectorIconId::VECTOR_ICON_NONE; |
| +} |
| + |
| static PowerStatus* g_power_status = NULL; |
| // Minimum battery percentage rendered in UI. |
| @@ -262,35 +282,116 @@ std::string PowerStatus::GetCurrentPowerSourceID() const { |
| PowerStatus::BatteryImageInfo PowerStatus::GetBatteryImageInfo( |
| IconSet icon_set) const { |
| BatteryImageInfo info; |
| + info.icon_set = icon_set; |
| + |
| + if (!IsUsbChargerConnected() && !IsBatteryPresent()) { |
| + info.icon_badge = |
| + IsLinePowerConnected() ? ICON_BADGE_QUESTION : ICON_BADGE_X; |
| + return info; |
| + } |
| if (IsUsbChargerConnected()) { |
| - info.resource_id = |
| - (icon_set == ICON_DARK) |
| + info.icon_badge = ICON_BADGE_UNRELIABLE; |
| + } else if (IsLinePowerConnected()) { |
| + info.icon_badge = ICON_BADGE_BOLT; |
| + } else { |
| + info.icon_badge = ICON_BADGE_NONE; |
| + } |
| + |
| + // Ensure fill level is between 0 and 14. |
| + info.fill_level = |
| + static_cast<int>(GetBatteryPercent() / 100.0 * (kNumPowerImages - 1)); |
| + info.fill_level = std::max(std::min(info.fill_level, kNumPowerImages - 1), 0); |
| + |
| + if (info.fill_level == 0 && info.icon_badge == ICON_BADGE_NONE) { |
| + info.icon_badge = ICON_BADGE_ALERT; |
| + } |
| + |
| + return info; |
| +} |
| + |
| +PowerStatus::BatteryImageInfoNonMD PowerStatus::ConvertToBatteryImageInfoNonMD( |
| + const BatteryImageInfo info) const { |
| + BatteryImageInfoNonMD info_non_md; |
| + |
| + if (info.icon_badge == ICON_BADGE_UNRELIABLE) { |
| + info_non_md.resource_id = info.icon_set == ICON_DARK |
| ? IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE_DARK |
| : IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE; |
| } else { |
| - info.resource_id = (icon_set == ICON_DARK) |
| - ? IDR_AURA_UBER_TRAY_POWER_SMALL_DARK |
| - : IDR_AURA_UBER_TRAY_POWER_SMALL; |
| + info_non_md.resource_id = info.icon_set == ICON_DARK |
| + ? IDR_AURA_UBER_TRAY_POWER_SMALL_DARK |
| + : IDR_AURA_UBER_TRAY_POWER_SMALL; |
| } |
| - info.offset = IsUsbChargerConnected() ? 0 : (IsLinePowerConnected() ? 1 : 0); |
| + info_non_md.offset = |
| + (info.icon_badge == ICON_BADGE_BOLT || |
| + info.icon_badge == ICON_BADGE_QUESTION) ? 1 : 0; |
| - if (GetBatteryPercent() >= 100.0) { |
| - info.index = kNumPowerImages - 1; |
| - } else if (!IsBatteryPresent()) { |
| - info.index = kNumPowerImages; |
| + if (info.icon_badge == ICON_BADGE_X || |
| + info.icon_badge == ICON_BADGE_QUESTION) { |
| + info_non_md.index = kNumPowerImages; |
| } else { |
| - info.index = |
| - static_cast<int>(GetBatteryPercent() / 100.0 * (kNumPowerImages - 1)); |
| - info.index = std::max(std::min(info.index, kNumPowerImages - 2), 0); |
| + CHECK_LE(info.fill_level, kNumPowerImages - 1); |
| + info_non_md.index = info.fill_level; |
| } |
| - return info; |
| + return info_non_md; |
| } |
| -gfx::ImageSkia PowerStatus::GetBatteryImage(IconSet icon_set) const { |
| - const BatteryImageInfo info = GetBatteryImageInfo(icon_set); |
| +gfx::ImageSkia PowerStatus::GetBatteryImage(const BatteryImageInfo info) const { |
| + // Terry - use a flag here. |
| + const bool use_md = true; |
| + if (!use_md) { |
| + return GetBatteryImageNonMD(ConvertToBatteryImageInfoNonMD(info)); |
| + } |
| + |
| + // Terry - figure out what these should actually be, move them to const file. |
| + const SkColor kBackgroundColor = |
| + info.icon_set == ICON_LIGHT ? SK_ColorGRAY : SK_ColorLTGRAY; |
| + const SkColor kFillColor = |
|
Evan Stade
2016/06/13 17:37:20
this is kind of confusing as a name, because to me
tdanderson
2016/06/20 23:06:53
I picked the terminology that is being used in the
Evan Stade
2016/06/21 02:55:48
yes, I still don't like "fill". I'm not surprised
tdanderson
2016/06/21 22:42:28
fill -> charge changed everywhere
|
| + info.icon_set == ICON_LIGHT ? SK_ColorWHITE : SK_ColorGRAY; |
| + const SkColor kBadgeColor = |
|
Evan Stade
2016/06/13 17:37:20
is there just one badge color? It isn't one color
tdanderson
2016/06/20 23:06:53
Clarified in next patch set.
|
| + info.icon_set == ICON_LIGHT ? SK_ColorDKGRAY : SK_ColorBLACK; |
| + |
| + // |fill_height| represents the number of pixels that should be drawn as the |
| + // fill color, upwards from the bottom of the 16x16 grid. Note that there is |
| + // 2px of bottom padding baked into the battery icon, which means that no |
| + // fill amount will be visible inside the battery for an |info.fill_level| |
| + // of 0 or 1. |
| + const int fill_height = |
| + (info.icon_badge == ICON_BADGE_X || |
| + info.icon_badge == ICON_BADGE_QUESTION) |
| + ? 0 |
| + : info.fill_level + 1; |
| + const int kImageSize = 16; |
| + gfx::Canvas canvas(gfx::Size(kImageSize, kImageSize), 1.0f, true); |
| + canvas.FillRect( |
| + gfx::Rect(0, kImageSize - fill_height, kImageSize, fill_height), |
| + kFillColor); |
| + canvas.FillRect( |
| + gfx::Rect(0, 0, kImageSize, kImageSize - fill_height), |
| + kBackgroundColor); |
| + |
| + // Mask the drawing of the background fill level to the shape of the battery. |
|
Evan Stade
2016/06/13 17:37:20
this masking idea seems like a fine approach but I
tdanderson
2016/06/20 23:06:53
Yes, this is much better, thanks. Changed to this
|
| + gfx::ImageSkia background(canvas.ExtractImageRep()); |
| + gfx::ImageSkia battery = CreateVectorIcon( |
| + gfx::VectorIconId::SYSTEM_TRAY_BATTERY, kBackgroundColor); |
| + gfx::ImageSkia filled_battery = |
| + gfx::ImageSkiaOperations::CreateMaskedImage(background, battery); |
| + |
| + // Draw a badge (exclamation mark, lightning bolt, etc) on top of the battery |
| + // icon, if applicable. |
| + if (info.icon_badge == ICON_BADGE_NONE) |
| + return filled_battery; |
| + gfx::ImageSkia overlay = CreateVectorIcon( |
| + VectorIconIdForIconBadge(info.icon_badge), kBadgeColor); |
| + return gfx::ImageSkiaOperations::CreateSuperimposedImage(filled_battery, |
| + overlay); |
| +} |
| + |
| +gfx::ImageSkia PowerStatus::GetBatteryImageNonMD( |
| + const BatteryImageInfoNonMD info) const { |
| gfx::Image all; |
| all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(info.resource_id); |
| gfx::Rect region(info.offset * kBatteryImageWidth, |