Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: ash/system/chromeos/power/power_status.cc

Issue 2063633002: Render Ash material design battery image icon without PNGs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "ash/system/chromeos/power/power_status.h" 5 #include "ash/system/chromeos/power/power_status.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "ash/shell.h" 10 #include "ash/shell.h"
11 #include "ash/shell_delegate.h" 11 #include "ash/shell_delegate.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "chromeos/dbus/dbus_thread_manager.h" 15 #include "chromeos/dbus/dbus_thread_manager.h"
16 #include "chromeos/dbus/power_manager_client.h" 16 #include "chromeos/dbus/power_manager_client.h"
17 #include "grit/ash_resources.h" 17 #include "grit/ash_resources.h"
18 #include "grit/ash_strings.h" 18 #include "grit/ash_strings.h"
19 #include "ui/base/l10n/l10n_util.h" 19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/base/l10n/time_format.h" 20 #include "ui/base/l10n/time_format.h"
21 #include "ui/base/resource/resource_bundle.h" 21 #include "ui/base/resource/resource_bundle.h"
22 #include "ui/gfx/canvas.h"
22 #include "ui/gfx/geometry/rect.h" 23 #include "ui/gfx/geometry/rect.h"
23 #include "ui/gfx/image/image.h" 24 #include "ui/gfx/image/image.h"
24 #include "ui/gfx/image/image_skia_operations.h" 25 #include "ui/gfx/image/image_skia_operations.h"
26 #include "ui/gfx/paint_vector_icon.h"
27 #include "ui/gfx/vector_icons_public.h"
25 28
26 namespace ash { 29 namespace ash {
27 namespace { 30 namespace {
28 31
29 // Updates |proto| to ensure that its fields are consistent. 32 // Updates |proto| to ensure that its fields are consistent.
30 void SanitizeProto(power_manager::PowerSupplyProperties* proto) { 33 void SanitizeProto(power_manager::PowerSupplyProperties* proto) {
31 DCHECK(proto); 34 DCHECK(proto);
32 35
33 if (proto->battery_state() == 36 if (proto->battery_state() ==
34 power_manager::PowerSupplyProperties_BatteryState_FULL) 37 power_manager::PowerSupplyProperties_BatteryState_FULL)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 return IDS_ASH_POWER_SOURCE_PORT_RIGHT_BACK; 91 return IDS_ASH_POWER_SOURCE_PORT_RIGHT_BACK;
89 case power_manager::PowerSupplyProperties_PowerSource_Port_BACK_LEFT: 92 case power_manager::PowerSupplyProperties_PowerSource_Port_BACK_LEFT:
90 return IDS_ASH_POWER_SOURCE_PORT_BACK_LEFT; 93 return IDS_ASH_POWER_SOURCE_PORT_BACK_LEFT;
91 case power_manager::PowerSupplyProperties_PowerSource_Port_BACK_RIGHT: 94 case power_manager::PowerSupplyProperties_PowerSource_Port_BACK_RIGHT:
92 return IDS_ASH_POWER_SOURCE_PORT_BACK_RIGHT; 95 return IDS_ASH_POWER_SOURCE_PORT_BACK_RIGHT;
93 } 96 }
94 NOTREACHED(); 97 NOTREACHED();
95 return 0; 98 return 0;
96 } 99 }
97 100
101 gfx::VectorIconId VectorIconIdForIconBadge(PowerStatus::IconBadge icon_badge) {
102 // TODO(tdanderson): Create vector icons for remaining types. See
103 // crbug.com/617298.
104 switch (icon_badge) {
105 case PowerStatus::ICON_BADGE_NONE:
106 return gfx::VectorIconId::VECTOR_ICON_NONE;
107 case PowerStatus::ICON_BADGE_ALERT:
108 case PowerStatus::ICON_BADGE_X:
109 case PowerStatus::ICON_BADGE_BOLT:
110 case PowerStatus::ICON_BADGE_QUESTION:
111 case PowerStatus::ICON_BADGE_UNRELIABLE:
112 return gfx::VectorIconId::SYSTEM_TRAY_BATTERY_BOLT_TEST;
113 }
114 NOTREACHED();
115 return gfx::VectorIconId::VECTOR_ICON_NONE;
116 }
117
98 static PowerStatus* g_power_status = NULL; 118 static PowerStatus* g_power_status = NULL;
99 119
100 // Minimum battery percentage rendered in UI. 120 // Minimum battery percentage rendered in UI.
101 const int kMinBatteryPercent = 1; 121 const int kMinBatteryPercent = 1;
102 122
103 // Width and height of battery images. 123 // Width and height of battery images.
104 const int kBatteryImageHeight = 25; 124 const int kBatteryImageHeight = 25;
105 const int kBatteryImageWidth = 25; 125 const int kBatteryImageWidth = 25;
106 126
107 // Number of different power states. 127 // Number of different power states.
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 return sources; 275 return sources;
256 } 276 }
257 277
258 std::string PowerStatus::GetCurrentPowerSourceID() const { 278 std::string PowerStatus::GetCurrentPowerSourceID() const {
259 return proto_.external_power_source_id(); 279 return proto_.external_power_source_id();
260 } 280 }
261 281
262 PowerStatus::BatteryImageInfo PowerStatus::GetBatteryImageInfo( 282 PowerStatus::BatteryImageInfo PowerStatus::GetBatteryImageInfo(
263 IconSet icon_set) const { 283 IconSet icon_set) const {
264 BatteryImageInfo info; 284 BatteryImageInfo info;
285 info.icon_set = icon_set;
286
287 if (!IsUsbChargerConnected() && !IsBatteryPresent()) {
288 info.icon_badge =
289 IsLinePowerConnected() ? ICON_BADGE_QUESTION : ICON_BADGE_X;
290 return info;
291 }
265 292
266 if (IsUsbChargerConnected()) { 293 if (IsUsbChargerConnected()) {
267 info.resource_id = 294 info.icon_badge = ICON_BADGE_UNRELIABLE;
268 (icon_set == ICON_DARK) 295 } else if (IsLinePowerConnected()) {
269 ? IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE_DARK 296 info.icon_badge = ICON_BADGE_BOLT;
270 : IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE;
271 } else { 297 } else {
272 info.resource_id = (icon_set == ICON_DARK) 298 info.icon_badge = ICON_BADGE_NONE;
273 ? IDR_AURA_UBER_TRAY_POWER_SMALL_DARK
274 : IDR_AURA_UBER_TRAY_POWER_SMALL;
275 } 299 }
276 300
277 info.offset = IsUsbChargerConnected() ? 0 : (IsLinePowerConnected() ? 1 : 0); 301 // Ensure fill level is between 0 and 14.
302 info.fill_level =
303 static_cast<int>(GetBatteryPercent() / 100.0 * (kNumPowerImages - 1));
304 info.fill_level = std::max(std::min(info.fill_level, kNumPowerImages - 1), 0);
278 305
279 if (GetBatteryPercent() >= 100.0) { 306 if (info.fill_level == 0 && info.icon_badge == ICON_BADGE_NONE) {
280 info.index = kNumPowerImages - 1; 307 info.icon_badge = ICON_BADGE_ALERT;
281 } else if (!IsBatteryPresent()) {
282 info.index = kNumPowerImages;
283 } else {
284 info.index =
285 static_cast<int>(GetBatteryPercent() / 100.0 * (kNumPowerImages - 1));
286 info.index = std::max(std::min(info.index, kNumPowerImages - 2), 0);
287 } 308 }
288 309
289 return info; 310 return info;
290 } 311 }
291 312
292 gfx::ImageSkia PowerStatus::GetBatteryImage(IconSet icon_set) const { 313 PowerStatus::BatteryImageInfoNonMD PowerStatus::ConvertToBatteryImageInfoNonMD(
293 const BatteryImageInfo info = GetBatteryImageInfo(icon_set); 314 const BatteryImageInfo info) const {
315 BatteryImageInfoNonMD info_non_md;
316
317 if (info.icon_badge == ICON_BADGE_UNRELIABLE) {
318 info_non_md.resource_id = info.icon_set == ICON_DARK
319 ? IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE_DARK
320 : IDR_AURA_UBER_TRAY_POWER_SMALL_CHARGING_UNRELIABLE;
321 } else {
322 info_non_md.resource_id = info.icon_set == ICON_DARK
323 ? IDR_AURA_UBER_TRAY_POWER_SMALL_DARK
324 : IDR_AURA_UBER_TRAY_POWER_SMALL;
325 }
326
327 info_non_md.offset =
328 (info.icon_badge == ICON_BADGE_BOLT ||
329 info.icon_badge == ICON_BADGE_QUESTION) ? 1 : 0;
330
331 if (info.icon_badge == ICON_BADGE_X ||
332 info.icon_badge == ICON_BADGE_QUESTION) {
333 info_non_md.index = kNumPowerImages;
334 } else {
335 CHECK_LE(info.fill_level, kNumPowerImages - 1);
336 info_non_md.index = info.fill_level;
337 }
338
339 return info_non_md;
340 }
341
342 gfx::ImageSkia PowerStatus::GetBatteryImage(const BatteryImageInfo info) const {
343 // Terry - use a flag here.
344 const bool use_md = true;
345 if (!use_md) {
346 return GetBatteryImageNonMD(ConvertToBatteryImageInfoNonMD(info));
347 }
348
349 // Terry - figure out what these should actually be, move them to const file.
350 const SkColor kBackgroundColor =
351 info.icon_set == ICON_LIGHT ? SK_ColorGRAY : SK_ColorLTGRAY;
352 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
353 info.icon_set == ICON_LIGHT ? SK_ColorWHITE : SK_ColorGRAY;
354 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.
355 info.icon_set == ICON_LIGHT ? SK_ColorDKGRAY : SK_ColorBLACK;
356
357 // |fill_height| represents the number of pixels that should be drawn as the
358 // fill color, upwards from the bottom of the 16x16 grid. Note that there is
359 // 2px of bottom padding baked into the battery icon, which means that no
360 // fill amount will be visible inside the battery for an |info.fill_level|
361 // of 0 or 1.
362 const int fill_height =
363 (info.icon_badge == ICON_BADGE_X ||
364 info.icon_badge == ICON_BADGE_QUESTION)
365 ? 0
366 : info.fill_level + 1;
367 const int kImageSize = 16;
368 gfx::Canvas canvas(gfx::Size(kImageSize, kImageSize), 1.0f, true);
369 canvas.FillRect(
370 gfx::Rect(0, kImageSize - fill_height, kImageSize, fill_height),
371 kFillColor);
372 canvas.FillRect(
373 gfx::Rect(0, 0, kImageSize, kImageSize - fill_height),
374 kBackgroundColor);
375
376 // 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
377 gfx::ImageSkia background(canvas.ExtractImageRep());
378 gfx::ImageSkia battery = CreateVectorIcon(
379 gfx::VectorIconId::SYSTEM_TRAY_BATTERY, kBackgroundColor);
380 gfx::ImageSkia filled_battery =
381 gfx::ImageSkiaOperations::CreateMaskedImage(background, battery);
382
383 // Draw a badge (exclamation mark, lightning bolt, etc) on top of the battery
384 // icon, if applicable.
385 if (info.icon_badge == ICON_BADGE_NONE)
386 return filled_battery;
387 gfx::ImageSkia overlay = CreateVectorIcon(
388 VectorIconIdForIconBadge(info.icon_badge), kBadgeColor);
389 return gfx::ImageSkiaOperations::CreateSuperimposedImage(filled_battery,
390 overlay);
391 }
392
393 gfx::ImageSkia PowerStatus::GetBatteryImageNonMD(
394 const BatteryImageInfoNonMD info) const {
294 gfx::Image all; 395 gfx::Image all;
295 all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(info.resource_id); 396 all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(info.resource_id);
296 gfx::Rect region(info.offset * kBatteryImageWidth, 397 gfx::Rect region(info.offset * kBatteryImageWidth,
297 info.index * kBatteryImageHeight, kBatteryImageWidth, 398 info.index * kBatteryImageHeight, kBatteryImageWidth,
298 kBatteryImageHeight); 399 kBatteryImageHeight);
299 return gfx::ImageSkiaOperations::ExtractSubset(*all.ToImageSkia(), region); 400 return gfx::ImageSkiaOperations::ExtractSubset(*all.ToImageSkia(), region);
300 } 401 }
301 402
302 base::string16 PowerStatus::GetAccessibleNameString( 403 base::string16 PowerStatus::GetAccessibleNameString(
303 bool full_description) const { 404 bool full_description) const {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 } 465 }
365 466
366 void PowerStatus::PowerChanged( 467 void PowerStatus::PowerChanged(
367 const power_manager::PowerSupplyProperties& proto) { 468 const power_manager::PowerSupplyProperties& proto) {
368 proto_ = proto; 469 proto_ = proto;
369 SanitizeProto(&proto_); 470 SanitizeProto(&proto_);
370 FOR_EACH_OBSERVER(Observer, observers_, OnPowerStatusChanged()); 471 FOR_EACH_OBSERVER(Observer, observers_, OnPowerStatusChanged());
371 } 472 }
372 473
373 } // namespace ash 474 } // namespace ash
OLDNEW
« no previous file with comments | « ash/system/chromeos/power/power_status.h ('k') | ash/system/chromeos/power/power_status_view.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698