OLD | NEW |
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 "base/string_number_conversions.h" | 7 #include "base/string_number_conversions.h" |
8 #include "base/time.h" | 8 #include "base/time.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "chrome/browser/chromeos/cros/cros_library.h" | 10 #include "chrome/browser/chromeos/cros/cros_library.h" |
11 #include "grit/generated_resources.h" | 11 #include "grit/generated_resources.h" |
12 #include "grit/theme_resources.h" | 12 #include "grit/theme_resources.h" |
13 #include "ui/base/l10n/l10n_util.h" | 13 #include "ui/base/l10n/l10n_util.h" |
14 #include "ui/base/resource/resource_bundle.h" | 14 #include "ui/base/resource/resource_bundle.h" |
15 #include "ui/gfx/canvas.h" | 15 #include "ui/gfx/canvas.h" |
| 16 #include "views/widget/widget.h" |
| 17 #include "views/window/window.h" |
| 18 |
| 19 using views::MenuItemView; |
| 20 |
| 21 namespace { |
| 22 |
| 23 // Menu item ids. |
| 24 enum { |
| 25 POWER_BATTERY_PERCENTAGE_ITEM, |
| 26 POWER_BATTERY_IS_CHARGED_ITEM, |
| 27 }; |
| 28 |
| 29 const int kNumPowerImages = 16; |
| 30 |
| 31 } // namespace |
16 | 32 |
17 namespace chromeos { | 33 namespace chromeos { |
18 | 34 |
19 //////////////////////////////////////////////////////////////////////////////// | 35 // PowerMenuButton ------------------------------------------------------------ |
20 // PowerMenuButton | |
21 | |
22 // static | |
23 const int PowerMenuButton::kNumPowerImages = 16; | |
24 | 36 |
25 PowerMenuButton::PowerMenuButton() | 37 PowerMenuButton::PowerMenuButton() |
26 : StatusAreaButton(this), | 38 : StatusAreaButton(this), |
27 battery_is_present_(false), | 39 battery_is_present_(false), |
28 line_power_on_(false), | 40 line_power_on_(false), |
29 battery_fully_charged_(false), | 41 battery_fully_charged_(false), |
30 battery_percentage_(0.0), | 42 battery_percentage_(0.0), |
31 icon_id_(-1), | 43 icon_id_(-1) { |
32 ALLOW_THIS_IN_INITIALIZER_LIST(power_menu_(this)) { | |
33 UpdateIconAndLabelInfo(); | 44 UpdateIconAndLabelInfo(); |
34 CrosLibrary::Get()->GetPowerLibrary()->AddObserver(this); | 45 CrosLibrary::Get()->GetPowerLibrary()->AddObserver(this); |
35 } | 46 } |
36 | 47 |
37 PowerMenuButton::~PowerMenuButton() { | 48 PowerMenuButton::~PowerMenuButton() { |
38 CrosLibrary::Get()->GetPowerLibrary()->RemoveObserver(this); | 49 CrosLibrary::Get()->GetPowerLibrary()->RemoveObserver(this); |
39 } | 50 } |
40 | 51 |
41 //////////////////////////////////////////////////////////////////////////////// | 52 // PowerMenuButton, views::MenuDelegate implementation: ----------------------- |
42 // PowerMenuButton, ui::MenuModel implementation: | |
43 | 53 |
44 int PowerMenuButton::GetItemCount() const { | 54 std::wstring PowerMenuButton::GetLabel(int id) const { |
45 return 2; | 55 string16 label; |
| 56 switch (id) { |
| 57 case POWER_BATTERY_PERCENTAGE_ITEM: |
| 58 label = GetBatteryPercentageText(); |
| 59 break; |
| 60 case POWER_BATTERY_IS_CHARGED_ITEM: |
| 61 label = GetBatteryIsChargedText(); |
| 62 break; |
| 63 default: |
| 64 NOTREACHED(); |
| 65 } |
| 66 |
| 67 return UTF16ToWide(label); |
46 } | 68 } |
47 | 69 |
48 ui::MenuModel::ItemType PowerMenuButton::GetTypeAt(int index) const { | 70 bool PowerMenuButton::IsCommandEnabled(int id) const { |
49 return ui::MenuModel::TYPE_COMMAND; | 71 return false; |
50 } | 72 } |
51 | 73 |
52 string16 PowerMenuButton::GetLabelAt(int index) const { | 74 // PowerMenuButton, views::View implementation: ------------------------------- |
53 // The first item shows the percentage of battery left. | |
54 if (index == 0) { | |
55 return l10n_util::GetStringFUTF16(IDS_STATUSBAR_BATTERY_PERCENTAGE, | |
56 base::IntToString16(static_cast<int>(battery_percentage_))); | |
57 } else if (index == 1) { | |
58 // The second item shows the battery is charged if it is. | |
59 if (battery_fully_charged_) | |
60 return l10n_util::GetStringUTF16(IDS_STATUSBAR_BATTERY_IS_CHARGED); | |
61 | 75 |
62 // If battery is in an intermediate charge state, show how much time left. | |
63 base::TimeDelta time = line_power_on_ ? battery_time_to_full_ : | |
64 battery_time_to_empty_; | |
65 if (time.InSeconds() == 0) { | |
66 // If time is 0, then that means we are still calculating how much time. | |
67 // Depending if line power is on, we either show a message saying that we | |
68 // are calculating time until full or calculating remaining time. | |
69 int msg = line_power_on_ ? | |
70 IDS_STATUSBAR_BATTERY_CALCULATING_TIME_UNTIL_FULL : | |
71 IDS_STATUSBAR_BATTERY_CALCULATING_TIME_UNTIL_EMPTY; | |
72 return l10n_util::GetStringUTF16(msg); | |
73 } else { | |
74 // Depending if line power is on, we either show a message saying XX:YY | |
75 // until full or XX:YY remaining where XX is number of hours and YY is | |
76 // number of minutes. | |
77 int msg = line_power_on_ ? IDS_STATUSBAR_BATTERY_TIME_UNTIL_FULL : | |
78 IDS_STATUSBAR_BATTERY_TIME_UNTIL_EMPTY; | |
79 int hour = time.InHours(); | |
80 int min = (time - base::TimeDelta::FromHours(hour)).InMinutes(); | |
81 string16 hour_str = base::IntToString16(hour); | |
82 string16 min_str = base::IntToString16(min); | |
83 // Append a "0" before the minute if it's only a single digit. | |
84 if (min < 10) | |
85 min_str = ASCIIToUTF16("0") + min_str; | |
86 return l10n_util::GetStringFUTF16(msg, hour_str, min_str); | |
87 } | |
88 } else { | |
89 NOTREACHED(); | |
90 return string16(); | |
91 } | |
92 } | |
93 | |
94 //////////////////////////////////////////////////////////////////////////////// | |
95 // PowerMenuButton, views::View implementation: | |
96 void PowerMenuButton::OnLocaleChanged() { | 76 void PowerMenuButton::OnLocaleChanged() { |
97 UpdateIconAndLabelInfo(); | 77 UpdateIconAndLabelInfo(); |
98 } | 78 } |
99 | 79 |
100 //////////////////////////////////////////////////////////////////////////////// | 80 // PowerMenuButton, views::ViewMenuDelegate implementation: ------------------- |
101 // PowerMenuButton, views::ViewMenuDelegate implementation: | |
102 | 81 |
103 void PowerMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { | 82 void PowerMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { |
104 power_menu_.Rebuild(); | 83 // View passed in must be a views::MenuButton, i.e. the PowerMenuButton. |
105 power_menu_.RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); | 84 DCHECK_EQ(this, source); |
| 85 |
| 86 if (!menu_.get()) { |
| 87 menu_.reset(new MenuItemView(this)); |
| 88 |
| 89 // Create menu items whose text will be supplied by GetLabel(). |
| 90 menu_->AppendDelegateMenuItem(POWER_BATTERY_PERCENTAGE_ITEM); |
| 91 menu_->AppendDelegateMenuItem(POWER_BATTERY_IS_CHARGED_ITEM); |
| 92 } |
| 93 |
| 94 // TODO(rhashimoto): Remove this workaround when WebUI provides a |
| 95 // top-level widget on the ChromeOS login screen that is a window. |
| 96 // The current BackgroundView class for the ChromeOS login screen |
| 97 // creates a owning Widget that has a native GtkWindow but is not a |
| 98 // Window. This makes it impossible to get the NativeWindow via |
| 99 // the views API. This workaround casts the top-level NativeWidget |
| 100 // to a NativeWindow that we can pass to MenuItemView::RunMenuAt(). |
| 101 gfx::NativeWindow window; |
| 102 if (source->GetWindow()) |
| 103 window = source->GetWindow()->GetNativeWindow(); |
| 104 else |
| 105 window = GTK_WINDOW(source->GetWidget()->GetNativeView()); |
| 106 |
| 107 gfx::Point screen_loc; |
| 108 views::View::ConvertPointToScreen(source, &screen_loc); |
| 109 gfx::Rect bounds(screen_loc, source->size()); |
| 110 menu_->RunMenuAt( |
| 111 window, |
| 112 this, |
| 113 bounds, |
| 114 base::i18n::IsRTL() ? MenuItemView::TOPLEFT : MenuItemView::TOPRIGHT, |
| 115 true); |
106 } | 116 } |
107 | 117 |
108 //////////////////////////////////////////////////////////////////////////////// | 118 // PowerMenuButton, PowerLibrary::Observer implementation: -------------------- |
109 // PowerMenuButton, PowerLibrary::Observer implementation: | |
110 | 119 |
111 void PowerMenuButton::PowerChanged(PowerLibrary* obj) { | 120 void PowerMenuButton::PowerChanged(PowerLibrary* obj) { |
112 UpdateIconAndLabelInfo(); | 121 UpdateIconAndLabelInfo(); |
113 } | 122 } |
114 | 123 |
115 //////////////////////////////////////////////////////////////////////////////// | 124 // PowerMenuButton implementation: -------------------------------------------- |
116 // PowerMenuButton, StatusAreaButton implementation: | 125 |
| 126 string16 PowerMenuButton::GetBatteryPercentageText() const |
| 127 { |
| 128 return l10n_util::GetStringFUTF16( |
| 129 IDS_STATUSBAR_BATTERY_PERCENTAGE, |
| 130 base::IntToString16(static_cast<int>(battery_percentage_))); |
| 131 } |
| 132 |
| 133 string16 PowerMenuButton::GetBatteryIsChargedText() const |
| 134 { |
| 135 if (battery_fully_charged_) |
| 136 return l10n_util::GetStringUTF16(IDS_STATUSBAR_BATTERY_IS_CHARGED); |
| 137 |
| 138 // If battery is in an intermediate charge state, show how |
| 139 // much time left. |
| 140 base::TimeDelta time = line_power_on_ ? battery_time_to_full_ : |
| 141 battery_time_to_empty_; |
| 142 if (time.InSeconds() == 0) { |
| 143 // If time is 0, then that means we are still calculating how much time. |
| 144 // Depending if line power is on, we either show a message saying that we |
| 145 // are calculating time until full or calculating remaining time. |
| 146 int msg = line_power_on_ ? |
| 147 IDS_STATUSBAR_BATTERY_CALCULATING_TIME_UNTIL_FULL : |
| 148 IDS_STATUSBAR_BATTERY_CALCULATING_TIME_UNTIL_EMPTY; |
| 149 return l10n_util::GetStringUTF16(msg); |
| 150 } else { |
| 151 // Depending if line power is on, we either show a message saying XX:YY |
| 152 // until full or XX:YY remaining where XX is number of hours and YY is |
| 153 // number of minutes. |
| 154 int msg = line_power_on_ ? IDS_STATUSBAR_BATTERY_TIME_UNTIL_FULL : |
| 155 IDS_STATUSBAR_BATTERY_TIME_UNTIL_EMPTY; |
| 156 int hour = time.InHours(); |
| 157 int min = (time - base::TimeDelta::FromHours(hour)).InMinutes(); |
| 158 string16 hour_str = base::IntToString16(hour); |
| 159 string16 min_str = base::IntToString16(min); |
| 160 // Append a "0" before the minute if it's only a single digit. |
| 161 if (min < 10) |
| 162 min_str = ASCIIToUTF16("0") + min_str; |
| 163 return l10n_util::GetStringFUTF16(msg, hour_str, min_str); |
| 164 } |
| 165 } |
117 | 166 |
118 void PowerMenuButton::UpdateIconAndLabelInfo() { | 167 void PowerMenuButton::UpdateIconAndLabelInfo() { |
119 PowerLibrary* cros = CrosLibrary::Get()->GetPowerLibrary(); | 168 PowerLibrary* cros = CrosLibrary::Get()->GetPowerLibrary(); |
120 if (!cros) | 169 if (!cros) |
121 return; | 170 return; |
122 | 171 |
123 bool cros_loaded = CrosLibrary::Get()->EnsureLoaded(); | 172 bool cros_loaded = CrosLibrary::Get()->EnsureLoaded(); |
124 if (cros_loaded) { | 173 if (cros_loaded) { |
125 battery_is_present_ = cros->battery_is_present(); | 174 battery_is_present_ = cros->battery_is_present(); |
126 line_power_on_ = cros->line_power_on(); | 175 line_power_on_ = cros->line_power_on(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 }; | 232 }; |
184 | 233 |
185 int index = static_cast<int>(battery_percentage_ / 100.0 * | 234 int index = static_cast<int>(battery_percentage_ / 100.0 * |
186 nextafter(static_cast<float>(kNumPowerImages), 0)); | 235 nextafter(static_cast<float>(kNumPowerImages), 0)); |
187 index = std::max(std::min(index, kNumPowerImages - 1), 0); | 236 index = std::max(std::min(index, kNumPowerImages - 1), 0); |
188 icon_id_ = line_power_on_ ? | 237 icon_id_ = line_power_on_ ? |
189 kChargingImages[index] : kDischargingImages[index]; | 238 kChargingImages[index] : kDischargingImages[index]; |
190 } | 239 } |
191 | 240 |
192 SetIcon(*ResourceBundle::GetSharedInstance().GetBitmapNamed(icon_id_)); | 241 SetIcon(*ResourceBundle::GetSharedInstance().GetBitmapNamed(icon_id_)); |
193 SetTooltipText(UTF16ToWide(GetLabelAt(0))); | 242 SetTooltipText(UTF16ToWide(GetBatteryPercentageText())); |
194 power_menu_.Rebuild(); | |
195 SchedulePaint(); | 243 SchedulePaint(); |
196 } | 244 } |
197 | 245 |
198 } // namespace chromeos | 246 } // namespace chromeos |
OLD | NEW |