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

Side by Side Diff: chrome/browser/chromeos/status/power_menu_button.cc

Issue 7491083: Implemented nicer battery status (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed unitialized ivars Created 9 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/power_menu_button.h" 5 #include "chrome/browser/chromeos/status/power_menu_button.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/string_number_conversions.h" 9 #include "base/string_number_conversions.h"
10 #include "base/time.h" 10 #include "base/time.h"
11 #include "base/utf_string_conversions.h" 11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/chromeos/cros/cros_library.h" 12 #include "chrome/browser/chromeos/cros/cros_library.h"
13 #include "grit/generated_resources.h" 13 #include "grit/generated_resources.h"
14 #include "grit/theme_resources.h" 14 #include "grit/theme_resources.h"
15 #include "ui/base/l10n/l10n_util.h" 15 #include "ui/base/l10n/l10n_util.h"
16 #include "ui/base/resource/resource_bundle.h" 16 #include "ui/base/resource/resource_bundle.h"
17 #include "ui/gfx/canvas.h" 17 #include "ui/gfx/canvas.h"
18 #include "ui/gfx/canvas_skia.h"
19 #include "ui/gfx/font.h"
18 #include "views/controls/menu/menu_item_view.h" 20 #include "views/controls/menu/menu_item_view.h"
19 #include "views/controls/menu/submenu_view.h" 21 #include "views/controls/menu/submenu_view.h"
20 #include "views/widget/widget.h" 22 #include "views/widget/widget.h"
21 23
22 namespace { 24 namespace {
23 25
24 // Menu item ids. 26 // Menu item ids.
25 enum { 27 enum {
26 POWER_BATTERY_PERCENTAGE_ITEM = 1000, 28 POWER_BATTERY_PERCENTAGE_ITEM = 1000,
27 POWER_BATTERY_IS_CHARGED_ITEM, 29 POWER_BATTERY_IS_CHARGED_ITEM,
28 POWER_NO_BATTERY, 30 POWER_NO_BATTERY,
29 }; 31 };
30 32
33 enum ImageType {
34 DISCHARGING,
35 CHARGING,
36 BOLT
37 };
38
39 enum ImageSize {
40 SMALL,
41 LARGE
42 };
43
44 // Initialize time deltas to large values so they will be replaced when set
45 // to small values.
46 const int64 kInitialMS = 0x7fffffff;
47 // Width and height of small images.
48 const int kSmallImageWidth = 26, kSmallImageHeight = 24;
49 // Width and height of large images.
50 const int kLargeImageWidth = 57, kLargeImageHeight = 35;
51 // Number of different power states.
52 const int kNumPowerImages = 20;
53
54 // Constants for status displayed when user clicks button.
55 // Padding around status.
56 const int kPadLeftX = 10, kPadRightX = 10, kPadY = 5;
57 // Padding between battery and text.
58 const int kBatteryPadX = 10;
59 // Spacing between lines of text.
60 const int kEstimateSpacing = 3;
61 // Color of text embedded within battery.
62 const SkColor kPercentageColor = 0xFF333333;
63 // Used for embossing text.
64 const SkColor kPercentageShadowColor = 0x80ffffff;
65 // Status text/
66 const SkColor kEstimateColor = SK_ColorBLACK;
67 // Size of percentage w/in battery.
68 const int kBatteryFontSizeDelta = 3;
69
70 // Battery images come from two collections (small and large). In each there
71 // are |kNumPowerImages| battery states for both on and off charge, followed
72 // by the missing battery image and the unknown image.
73 // They are layed out like this:
74 // Discharging Charging Bolt
75 // | | +
76 // || || +
77 // ...
78 // ||||| ||||| +
79 // ||X|| ||?||
80 SkBitmap GetImage(ImageSize size, ImageType type, int index) {
81 int image_width, image_height, image_index;
82
83 if (size == SMALL) {
84 image_index = IDR_STATUSBAR_BATTERY_SMALL_ALL;
85 image_width = kSmallImageWidth;
86 image_height = kSmallImageHeight;
87 } else {
88 image_index = IDR_STATUSBAR_BATTERY_LARGE_ALL;
89 image_width = kLargeImageWidth;
90 image_height = kLargeImageHeight;
91 }
92 SkBitmap* all_images =
93 ResourceBundle::GetSharedInstance().GetBitmapNamed(image_index);
94 SkBitmap image;
achuithb 2011/08/09 18:58:07 Maybe move this to right before extractSubset?
DaveMoore 2011/08/12 21:03:11 Done.
95 SkIRect subset =
96 SkIRect::MakeXYWH(
97 static_cast<int>(type) * image_width,
98 index * image_height,
99 image_width,
100 image_height);
101
102 all_images->extractSubset(&image, subset);
103 return image;
104 }
105
106 SkBitmap GetMissingImage(ImageSize size) {
107 return GetImage(size, DISCHARGING, kNumPowerImages);
108 }
109
110 SkBitmap GetUnknownImage(ImageSize size) {
111 return GetImage(size, CHARGING, kNumPowerImages);
112 }
113
31 } // namespace 114 } // namespace
32 115
33 namespace chromeos { 116 namespace chromeos {
34 117
35 using base::TimeDelta; 118 using base::TimeDelta;
36 119
120 class PowerMenuButton::StatusView : public View {
121 public:
122 explicit StatusView(PowerMenuButton* menu_button)
123 : menu_button_(menu_button) {
124 estimate_font_ =
125 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont);
126 percentage_font_ =
127 estimate_font_.DeriveFont(kBatteryFontSizeDelta, gfx::Font::BOLD);
128 }
129
130 gfx::Size GetPreferredSize() {
131 int estimate_w, estimate_h, charging_w, charging_h;
132 string16 estimate_text = menu_button_->GetBatteryIsChargedText();
133 string16 charging_text = l10n_util::GetStringUTF16(
134 menu_button_->line_power_on_ ?
135 IDS_STATUSBAR_BATTERY_CHARGING :
136 IDS_STATUSBAR_BATTERY_DISCHARGING);
137 gfx::CanvasSkia::SizeStringInt(
138 estimate_text, estimate_font_, &estimate_w, &estimate_h, 0);
139 gfx::CanvasSkia::SizeStringInt(
140 charging_text, estimate_font_, &charging_w, &charging_h, 0);
141 gfx::Size size = gfx::Size(
142 kPadLeftX + kLargeImageWidth + kBatteryPadX + kPadRightX +
143 std::max(charging_w, estimate_w),
144 (2 * kPadY) +
145 std::max(kLargeImageHeight,
146 kEstimateSpacing + (2 * estimate_font_.GetHeight())));
147 return size;
148 }
149
150 void Update() {
151 PreferredSizeChanged();
152 // Force a paint even if the size didn't change.
153 SchedulePaint();
154 }
155
156 protected:
157 void OnPaint(gfx::Canvas* canvas) {
158 SkBitmap image;
159
160 bool draw_percentage_text = false;
161 if (!CrosLibrary::Get()->EnsureLoaded()) {
162 image = GetUnknownImage(LARGE);
163 } else if (!menu_button_->battery_is_present_) {
164 image = GetMissingImage(LARGE);
165 } else {
166 image = GetImage(
167 LARGE,
168 menu_button_->line_power_on_ ? CHARGING : DISCHARGING,
169 menu_button_->battery_index_);
170 if (menu_button_->battery_percentage_ < 100 ||
171 !menu_button_->line_power_on_) {
172 draw_percentage_text = true;
173 }
174 }
175 int image_x = kPadLeftX, image_y = (height() - image.height()) / 2;
176
achuithb 2011/08/09 18:58:07 Shouldn't this newline be after DrawBitmapInt?
DaveMoore 2011/08/12 21:03:11 Done.
177 canvas->DrawBitmapInt(image, image_x, image_y);
178 if (draw_percentage_text) {
179 string16 text = UTF8ToUTF16(StringPrintf(
180 "%d%%",
181 static_cast<int>(menu_button_->battery_percentage_)));
182 int text_h = percentage_font_.GetHeight();
183 int text_y = ((height() - text_h) / 2);
184 canvas->DrawStringInt(
185 text, percentage_font_, kPercentageShadowColor,
186 image_x, text_y + 1, image.width(), text_h,
187 gfx::Canvas::TEXT_ALIGN_CENTER | gfx::Canvas::NO_ELLIPSIS);
188 canvas->DrawStringInt(
189 text, percentage_font_, kPercentageColor,
190 image_x, text_y, image.width(), text_h,
191 gfx::Canvas::TEXT_ALIGN_CENTER | gfx::Canvas::NO_ELLIPSIS);
192 if (menu_button_->line_power_on_) {
193 image = GetImage(LARGE, BOLT, menu_button_->battery_index_);
194 canvas->DrawBitmapInt(image, image_x, image_y);
195 }
196 }
197 string16 charging_text = l10n_util::GetStringUTF16(
198 menu_button_->line_power_on_ ?
199 IDS_STATUSBAR_BATTERY_CHARGING :
200 IDS_STATUSBAR_BATTERY_DISCHARGING);
201 string16 estimate_text = menu_button_->GetBatteryIsChargedText();
202 int text_h = estimate_font_.GetHeight();
203 int text_x = image_x + kLargeImageWidth + kBatteryPadX;
204 int charging_y = (height() - (kEstimateSpacing + (2 * text_h))) / 2;
205 int estimate_y = charging_y + text_h + kEstimateSpacing;
206 canvas->DrawStringInt(
207 charging_text, estimate_font_, kEstimateColor,
208 text_x, charging_y, width() - text_x, text_h,
209 gfx::Canvas::TEXT_ALIGN_LEFT);
210 canvas->DrawStringInt(
211 estimate_text, estimate_font_, kEstimateColor,
212 text_x, estimate_y, width() - text_x, text_h,
213 gfx::Canvas::TEXT_ALIGN_LEFT);
214 }
215
216 bool OnMousePressed(const views::MouseEvent& event) {
217 return true;
218 }
219
220 void OnMouseReleased(const views::MouseEvent& event) {
221 if (event.IsLeftMouseButton()) {
222 DCHECK(menu_button_->menu_);
223 menu_button_->menu_->Cancel();
224 }
225 }
226
227 private:
228 PowerMenuButton* menu_button_;
229 gfx::Font percentage_font_;
230 gfx::Font estimate_font_;
231 };
232
37 //////////////////////////////////////////////////////////////////////////////// 233 ////////////////////////////////////////////////////////////////////////////////
38 // PowerMenuButton 234 // PowerMenuButton
39 235
40 // static
41 const int PowerMenuButton::kNumPowerImages = 19;
42
43 PowerMenuButton::PowerMenuButton(StatusAreaHost* host) 236 PowerMenuButton::PowerMenuButton(StatusAreaHost* host)
44 : StatusAreaButton(host, this), 237 : StatusAreaButton(host, this),
45 battery_is_present_(false), 238 battery_is_present_(false),
46 line_power_on_(false), 239 line_power_on_(false),
47 battery_fully_charged_(false),
48 battery_percentage_(0.0), 240 battery_percentage_(0.0),
49 icon_id_(-1) { 241 battery_index_(-1),
242 battery_time_to_full_(TimeDelta::FromMicroseconds(kInitialMS)),
243 battery_time_to_empty_(TimeDelta::FromMicroseconds(kInitialMS)),
244 status_(NULL),
245 menu_(NULL) {
50 UpdateIconAndLabelInfo(); 246 UpdateIconAndLabelInfo();
51 CrosLibrary::Get()->GetPowerLibrary()->AddObserver(this); 247 CrosLibrary::Get()->GetPowerLibrary()->AddObserver(this);
52 } 248 }
53 249
54 PowerMenuButton::~PowerMenuButton() { 250 PowerMenuButton::~PowerMenuButton() {
55 CrosLibrary::Get()->GetPowerLibrary()->RemoveObserver(this); 251 CrosLibrary::Get()->GetPowerLibrary()->RemoveObserver(this);
56 } 252 }
57 253
58 // PowerMenuButton, views::MenuDelegate implementation: 254 // PowerMenuButton, views::MenuDelegate implementation:
59 255
60 std::wstring PowerMenuButton::GetLabel(int id) const { 256 std::wstring PowerMenuButton::GetLabel(int id) const {
61 string16 label; 257 return std::wstring();
achuithb 2011/08/09 18:58:07 What is GetLabel used for?
62 switch (id) {
63 case POWER_BATTERY_PERCENTAGE_ITEM:
64 label = GetBatteryPercentageText();
65 break;
66 case POWER_BATTERY_IS_CHARGED_ITEM:
67 label = GetBatteryIsChargedText();
68 break;
69 default:
70 NOTREACHED();
71 }
72
73 return UTF16ToWide(label);
74 } 258 }
75 259
76 bool PowerMenuButton::IsCommandEnabled(int id) const { 260 bool PowerMenuButton::IsCommandEnabled(int id) const {
77 return false; 261 return false;
78 } 262 }
79 263
80 string16 PowerMenuButton::GetBatteryPercentageText() const { 264 string16 PowerMenuButton::GetBatteryPercentageText() const {
81 return l10n_util::GetStringFUTF16( 265 return l10n_util::GetStringFUTF16(
82 IDS_STATUSBAR_BATTERY_PERCENTAGE, 266 IDS_STATUSBAR_BATTERY_PERCENTAGE,
83 base::IntToString16(static_cast<int>(battery_percentage_))); 267 base::IntToString16(static_cast<int>(battery_percentage_)));
84 } 268 }
85 269
86 string16 PowerMenuButton::GetBatteryIsChargedText() const { 270 string16 PowerMenuButton::GetBatteryIsChargedText() const {
87 // The second item shows the battery is charged if it is. 271 // The second item shows the battery is charged if it is.
88 if (battery_fully_charged_) 272 if (battery_percentage_ >= 100 && line_power_on_)
89 return l10n_util::GetStringUTF16(IDS_STATUSBAR_BATTERY_IS_CHARGED); 273 return l10n_util::GetStringUTF16(IDS_STATUSBAR_BATTERY_IS_CHARGED);
90 274
91 // If battery is in an intermediate charge state, show how much time left. 275 // If battery is in an intermediate charge state, show how much time left.
92 TimeDelta time = line_power_on_ ? battery_time_to_full_ : 276 TimeDelta time = line_power_on_ ? battery_time_to_full_ :
93 battery_time_to_empty_; 277 battery_time_to_empty_;
94 if (time.InSeconds() == 0) { 278 if (time.InSeconds() == 0) {
95 // If time is 0, then that means we are still calculating how much time. 279 // If time is 0, then that means we are still calculating how much time.
96 // Depending if line power is on, we either show a message saying that we 280 // Depending if line power is on, we either show a message saying that we
97 // are calculating time until full or calculating remaining time. 281 // are calculating time until full or calculating remaining time.
98 int msg = line_power_on_ ? 282 int msg = line_power_on_ ?
(...skipping 24 matching lines...) Expand all
123 //////////////////////////////////////////////////////////////////////////////// 307 ////////////////////////////////////////////////////////////////////////////////
124 // PowerMenuButton, views::View implementation: 308 // PowerMenuButton, views::View implementation:
125 void PowerMenuButton::OnLocaleChanged() { 309 void PowerMenuButton::OnLocaleChanged() {
126 UpdateIconAndLabelInfo(); 310 UpdateIconAndLabelInfo();
127 } 311 }
128 312
129 //////////////////////////////////////////////////////////////////////////////// 313 ////////////////////////////////////////////////////////////////////////////////
130 // PowerMenuButton, views::ViewMenuDelegate implementation: 314 // PowerMenuButton, views::ViewMenuDelegate implementation:
131 315
132 void PowerMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { 316 void PowerMenuButton::RunMenu(views::View* source, const gfx::Point& pt) {
133 UpdateMenu(); 317 menu_ = new views::MenuItemView(this);
318 views::MenuItemView* submenu =
319 menu_->AppendMenuItem(
320 POWER_BATTERY_PERCENTAGE_ITEM,
321 std::wstring(),
322 views::MenuItemView::NORMAL);
323 status_ = new StatusView(this);
324 submenu->AddChildView(status_);
325 menu_->CreateSubmenu()->set_resize_open_menu(true);
326 menu_->SetMargins(0, 0);
327 submenu->SetMargins(0, 0);
328 menu_->ChildrenChanged();
134 329
135 gfx::Point screen_location; 330 gfx::Point screen_location;
136 views::View::ConvertPointToScreen(source, &screen_location); 331 views::View::ConvertPointToScreen(source, &screen_location);
137 gfx::Rect bounds(screen_location, source->size()); 332 gfx::Rect bounds(screen_location, source->size());
138 menu_->RunMenuAt( 333 menu_->RunMenuAt(
139 source->GetWidget()->GetTopLevelWidget(), 334 source->GetWidget()->GetTopLevelWidget(),
140 this, 335 this,
141 bounds, 336 bounds,
142 views::MenuItemView::TOPRIGHT, 337 views::MenuItemView::TOPRIGHT,
143 true); 338 true);
339 delete menu_;
340 status_ = NULL;
achuithb 2011/08/09 18:58:07 Is status_ leaked or does AddChildView transfer ow
DaveMoore 2011/08/12 21:03:11 AddChildView transfers ownership. That aren't stac
341 menu_ = NULL;
144 } 342 }
145 343
146 //////////////////////////////////////////////////////////////////////////////// 344 ////////////////////////////////////////////////////////////////////////////////
147 // PowerMenuButton, PowerLibrary::Observer implementation: 345 // PowerMenuButton, PowerLibrary::Observer implementation:
148 346
149 void PowerMenuButton::PowerChanged(PowerLibrary* obj) { 347 void PowerMenuButton::PowerChanged(PowerLibrary* obj) {
150 UpdateIconAndLabelInfo(); 348 UpdateIconAndLabelInfo();
151 } 349 }
152 350
153 //////////////////////////////////////////////////////////////////////////////// 351 ////////////////////////////////////////////////////////////////////////////////
154 // PowerMenuButton, StatusAreaButton implementation: 352 // PowerMenuButton, StatusAreaButton implementation:
155 353
156 void PowerMenuButton::UpdateIconAndLabelInfo() { 354 void PowerMenuButton::UpdateIconAndLabelInfo() {
157 PowerLibrary* cros = CrosLibrary::Get()->GetPowerLibrary(); 355 PowerLibrary* cros = CrosLibrary::Get()->GetPowerLibrary();
158 if (!cros) 356 if (!cros)
159 return; 357 return;
160 358
161 bool cros_loaded = CrosLibrary::Get()->EnsureLoaded(); 359 bool cros_loaded = CrosLibrary::Get()->EnsureLoaded();
162 if (cros_loaded) { 360 if (cros_loaded) {
163 battery_is_present_ = cros->battery_is_present(); 361 battery_is_present_ = cros->battery_is_present();
164 line_power_on_ = cros->line_power_on(); 362 line_power_on_ = cros->line_power_on();
165 battery_fully_charged_ = cros->battery_fully_charged(); 363
166 battery_percentage_ = cros->battery_percentage();
167 // If fully charged, always show 100% even if internal number is a bit less. 364 // If fully charged, always show 100% even if internal number is a bit less.
168 // Note: we always call cros->battery_percentage() for test predictability. 365 if (cros->battery_fully_charged()) {
169 if (battery_fully_charged_) 366 // We always call cros->battery_percentage() for test predictability.
367 cros->battery_percentage();
170 battery_percentage_ = 100.0; 368 battery_percentage_ = 100.0;
171 // Map 1-100 to 0-100, so 1% shows up as 0%, and 100% remains 100%. 369 } else {
172 static const double k = 100.0/99; 370 battery_percentage_ = cros->battery_percentage();
173 battery_percentage_ = (battery_percentage_ > 1.0 ? 371 }
174 battery_percentage_ : 1.0) * k - k;
175 372
176 UpdateBatteryTime(&battery_time_to_full_, cros->battery_time_to_full()); 373 UpdateBatteryTime(&battery_time_to_full_, cros->battery_time_to_full());
177 UpdateBatteryTime(&battery_time_to_empty_, cros->battery_time_to_empty()); 374 UpdateBatteryTime(&battery_time_to_empty_, cros->battery_time_to_empty());
178 } 375 }
179 376
180 if (!cros_loaded) { 377 if (!cros_loaded) {
181 icon_id_ = IDR_STATUSBAR_BATTERY_UNKNOWN; 378 battery_index_ = -1;
379 SetIcon(GetUnknownImage(SMALL));
182 } else if (!battery_is_present_) { 380 } else if (!battery_is_present_) {
183 icon_id_ = IDR_STATUSBAR_BATTERY_MISSING; 381 battery_index_ = -1;
184 } else if (line_power_on_ && battery_fully_charged_) { 382 SetIcon(GetMissingImage(SMALL));
185 icon_id_ = IDR_STATUSBAR_BATTERY_CHARGED;
186 } else { 383 } else {
187 // Get the power image depending on battery percentage. Percentage is 384 // Preserve the fully charged icon for 100% only.
188 // from 0 to 100, so we need to convert that to 0 to kNumPowerImages - 1. 385 if (battery_percentage_ >= 100) {
189 // NOTE: Use an array rather than just calculating a resource number to 386 battery_index_ = kNumPowerImages - 1;
190 // avoid creating implicit ordering dependencies on the resource values. 387 } else {
191 static const int kChargingImages[kNumPowerImages] = { 388 battery_index_ =
192 IDR_STATUSBAR_BATTERY_CHARGING_1, 389 static_cast<int>(battery_percentage_ / 100.0 *
193 IDR_STATUSBAR_BATTERY_CHARGING_2, 390 nextafter(static_cast<float>(kNumPowerImages - 1), 0));
194 IDR_STATUSBAR_BATTERY_CHARGING_3, 391 battery_index_ =
195 IDR_STATUSBAR_BATTERY_CHARGING_4, 392 std::max(std::min(battery_index_, kNumPowerImages - 2), 0);
196 IDR_STATUSBAR_BATTERY_CHARGING_5, 393 }
197 IDR_STATUSBAR_BATTERY_CHARGING_6, 394 SetIcon(GetImage(
198 IDR_STATUSBAR_BATTERY_CHARGING_7, 395 SMALL, line_power_on_ ? CHARGING : DISCHARGING, battery_index_));
199 IDR_STATUSBAR_BATTERY_CHARGING_8,
200 IDR_STATUSBAR_BATTERY_CHARGING_9,
201 IDR_STATUSBAR_BATTERY_CHARGING_10,
202 IDR_STATUSBAR_BATTERY_CHARGING_11,
203 IDR_STATUSBAR_BATTERY_CHARGING_12,
204 IDR_STATUSBAR_BATTERY_CHARGING_13,
205 IDR_STATUSBAR_BATTERY_CHARGING_14,
206 IDR_STATUSBAR_BATTERY_CHARGING_15,
207 IDR_STATUSBAR_BATTERY_CHARGING_16,
208 IDR_STATUSBAR_BATTERY_CHARGING_17,
209 IDR_STATUSBAR_BATTERY_CHARGING_18,
210 IDR_STATUSBAR_BATTERY_CHARGING_19,
211 };
212 static const int kDischargingImages[kNumPowerImages] = {
213 IDR_STATUSBAR_BATTERY_DISCHARGING_1,
214 IDR_STATUSBAR_BATTERY_DISCHARGING_2,
215 IDR_STATUSBAR_BATTERY_DISCHARGING_3,
216 IDR_STATUSBAR_BATTERY_DISCHARGING_4,
217 IDR_STATUSBAR_BATTERY_DISCHARGING_5,
218 IDR_STATUSBAR_BATTERY_DISCHARGING_6,
219 IDR_STATUSBAR_BATTERY_DISCHARGING_7,
220 IDR_STATUSBAR_BATTERY_DISCHARGING_8,
221 IDR_STATUSBAR_BATTERY_DISCHARGING_9,
222 IDR_STATUSBAR_BATTERY_DISCHARGING_10,
223 IDR_STATUSBAR_BATTERY_DISCHARGING_11,
224 IDR_STATUSBAR_BATTERY_DISCHARGING_12,
225 IDR_STATUSBAR_BATTERY_DISCHARGING_13,
226 IDR_STATUSBAR_BATTERY_DISCHARGING_14,
227 IDR_STATUSBAR_BATTERY_DISCHARGING_15,
228 IDR_STATUSBAR_BATTERY_DISCHARGING_16,
229 IDR_STATUSBAR_BATTERY_DISCHARGING_17,
230 IDR_STATUSBAR_BATTERY_DISCHARGING_18,
231 IDR_STATUSBAR_BATTERY_DISCHARGING_19,
232 };
233
234 int index = static_cast<int>(battery_percentage_ / 100.0 *
235 nextafter(static_cast<float>(kNumPowerImages), 0));
236 index = std::max(std::min(index, kNumPowerImages - 1), 0);
237 icon_id_ = line_power_on_ ?
238 kChargingImages[index] : kDischargingImages[index];
239 } 396 }
240 397
241 SetIcon(*ResourceBundle::GetSharedInstance().GetBitmapNamed(icon_id_)); 398 percentage_text_ = GetBatteryPercentageText();
242 SetTooltipText(GetLabel(POWER_BATTERY_PERCENTAGE_ITEM)); 399 SetTooltipText(UTF16ToWide(percentage_text_));
243 SetAccessibleName(GetBatteryPercentageText()); 400 SetAccessibleName(percentage_text_);
244 UpdateMenu();
245 SchedulePaint(); 401 SchedulePaint();
402 if (status_)
403 status_->Update();
246 } 404 }
247 405
248 void PowerMenuButton::UpdateBatteryTime(TimeDelta* previous, 406 void PowerMenuButton::UpdateBatteryTime(TimeDelta* previous,
249 const TimeDelta& current) { 407 const TimeDelta& current) {
250 static const TimeDelta kMaxDiff(TimeDelta::FromMinutes(10)); 408 static const TimeDelta kMaxDiff(TimeDelta::FromMinutes(10));
251 static const TimeDelta kMinDiff(TimeDelta::FromMinutes(0)); 409 static const TimeDelta kMinDiff(TimeDelta::FromMinutes(0));
252 const TimeDelta diff = current - *previous; 410 const TimeDelta diff = current - *previous;
253 // If the diff is small and positive, ignore it in favor of 411 // If the diff is small and positive, ignore it in favor of
254 // keeping time monotonically decreasing. 412 // keeping time monotonically decreasing.
255 if (diff < kMinDiff || diff > kMaxDiff) 413 // If previous is 0, then it either was never set (initial condition)
414 // or got down to 0
achuithb 2011/08/09 18:58:07 period at end of comment.
DaveMoore 2011/08/12 21:03:11 Done.
415 if (*previous == TimeDelta::FromMicroseconds(kInitialMS) ||
416 diff < kMinDiff ||
417 diff > kMaxDiff) {
256 *previous = current; 418 *previous = current;
257 }
258
259 void PowerMenuButton::UpdateMenu() {
260 if (!menu_.get())
261 menu_.reset(new views::MenuItemView(this));
262
263 // Remove existing items.
264 const int old_count = menu_->CreateSubmenu()->child_count();
265 for (int i = 0; i < old_count; ++i)
266 menu_->RemoveMenuItemAt(0);
267
268 if (battery_is_present_) {
269 // Create menu items whose text will be supplied by GetLabel().
270 menu_->AppendDelegateMenuItem(POWER_BATTERY_PERCENTAGE_ITEM);
271 menu_->AppendDelegateMenuItem(POWER_BATTERY_IS_CHARGED_ITEM);
272 } else {
273 menu_->AppendMenuItemWithLabel(
274 POWER_NO_BATTERY,
275 UTF16ToWide(l10n_util::GetStringUTF16(IDS_STATUSBAR_NO_BATTERY)));
276 } 419 }
277 menu_->ChildrenChanged();
278 } 420 }
279 421
280 } // namespace chromeos 422 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698