• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ash/system/chromeos/power/power_status_view.h"
6 
7 #include "ash/shell.h"
8 #include "ash/shell_delegate.h"
9 #include "ash/system/chromeos/power/power_status.h"
10 #include "ash/system/chromeos/power/tray_power.h"
11 #include "ash/system/tray/fixed_sized_image_view.h"
12 #include "ash/system/tray/tray_constants.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "grit/ash_strings.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/l10n/time_format.h"
18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/views/controls/image_view.h"
20 #include "ui/views/controls/label.h"
21 #include "ui/views/layout/box_layout.h"
22 #include "ui/views/layout/grid_layout.h"
23 
24 namespace ash {
25 namespace internal {
26 
27 // Padding between battery status text and battery icon on default view.
28 const int kPaddingBetweenBatteryStatusAndIcon = 3;
29 
PowerStatusView(ViewType view_type,bool default_view_right_align)30 PowerStatusView::PowerStatusView(ViewType view_type,
31                                  bool default_view_right_align)
32     : default_view_right_align_(default_view_right_align),
33       status_label_(NULL),
34       time_label_(NULL),
35       time_status_label_(NULL),
36       percentage_label_(NULL),
37       icon_(NULL),
38       view_type_(view_type) {
39   PowerStatus::Get()->AddObserver(this);
40   if (view_type == VIEW_DEFAULT) {
41     time_status_label_ = new views::Label;
42     percentage_label_ = new views::Label;
43     percentage_label_->SetEnabledColor(kHeaderTextColorNormal);
44     LayoutDefaultView();
45   } else {
46     status_label_ = new views::Label;
47     time_label_ = new views::Label;
48     LayoutNotificationView();
49   }
50   OnPowerStatusChanged();
51 }
52 
~PowerStatusView()53 PowerStatusView::~PowerStatusView() {
54   PowerStatus::Get()->RemoveObserver(this);
55 }
56 
OnPowerStatusChanged()57 void PowerStatusView::OnPowerStatusChanged() {
58   view_type_ == VIEW_DEFAULT ?
59       UpdateTextForDefaultView() : UpdateTextForNotificationView();
60 
61   if (icon_) {
62     icon_->SetImage(
63         PowerStatus::Get()->GetBatteryImage(PowerStatus::ICON_DARK));
64     icon_->SetVisible(true);
65   }
66 }
67 
LayoutDefaultView()68 void PowerStatusView::LayoutDefaultView() {
69   if (default_view_right_align_) {
70     views::BoxLayout* layout =
71         new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0,
72                              kPaddingBetweenBatteryStatusAndIcon);
73     SetLayoutManager(layout);
74 
75     AddChildView(percentage_label_);
76     AddChildView(time_status_label_);
77 
78     icon_ = new views::ImageView;
79     AddChildView(icon_);
80   } else {
81     // PowerStatusView is left aligned on the system tray pop up item.
82     views::BoxLayout* layout =
83         new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0,
84                              kTrayPopupPaddingBetweenItems);
85     SetLayoutManager(layout);
86 
87     icon_ =
88         new ash::internal::FixedSizedImageView(0, ash::kTrayPopupItemHeight);
89     AddChildView(icon_);
90 
91     AddChildView(percentage_label_);
92     AddChildView(time_status_label_);
93   }
94 }
95 
LayoutNotificationView()96 void PowerStatusView::LayoutNotificationView() {
97   SetLayoutManager(
98       new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
99   status_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
100   AddChildView(status_label_);
101 
102   time_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
103   AddChildView(time_label_);
104 }
105 
UpdateTextForDefaultView()106 void PowerStatusView::UpdateTextForDefaultView() {
107   const PowerStatus& status = *PowerStatus::Get();
108   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
109   base::string16 battery_percentage;
110   base::string16 battery_time_status;
111 
112   if (status.IsBatteryFull()) {
113     battery_time_status =
114         rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_BATTERY_FULL);
115   } else {
116     battery_percentage = l10n_util::GetStringFUTF16(
117         IDS_ASH_STATUS_TRAY_BATTERY_PERCENT_ONLY,
118         base::IntToString16(status.GetRoundedBatteryPercent()));
119     if (status.IsUsbChargerConnected()) {
120       battery_time_status = rb.GetLocalizedString(
121           IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE);
122     } else if (status.IsBatteryTimeBeingCalculated()) {
123       battery_time_status =
124           rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING);
125     } else {
126       base::TimeDelta time = status.IsBatteryCharging() ?
127           status.GetBatteryTimeToFull() : status.GetBatteryTimeToEmpty();
128       if (PowerStatus::ShouldDisplayBatteryTime(time) &&
129           !status.IsBatteryDischargingOnLinePower()) {
130         int hour = 0, min = 0;
131         PowerStatus::SplitTimeIntoHoursAndMinutes(time, &hour, &min);
132         base::string16 minute = min < 10 ?
133             ASCIIToUTF16("0") + base::IntToString16(min) :
134             base::IntToString16(min);
135         battery_time_status =
136             l10n_util::GetStringFUTF16(
137                 status.IsBatteryCharging() ?
138                 IDS_ASH_STATUS_TRAY_BATTERY_TIME_UNTIL_FULL_SHORT :
139                 IDS_ASH_STATUS_TRAY_BATTERY_TIME_LEFT_SHORT,
140                 base::IntToString16(hour),
141                 minute);
142       }
143     }
144     battery_percentage = battery_time_status.empty() ?
145         battery_percentage : battery_percentage + ASCIIToUTF16(" - ");
146   }
147   percentage_label_->SetVisible(!battery_percentage.empty());
148   percentage_label_->SetText(battery_percentage);
149   time_status_label_->SetVisible(!battery_time_status.empty());
150   time_status_label_->SetText(battery_time_status);
151 }
152 
UpdateTextForNotificationView()153 void PowerStatusView::UpdateTextForNotificationView() {
154   const PowerStatus& status = *PowerStatus::Get();
155   if (status.IsBatteryFull()) {
156     status_label_->SetText(
157         ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
158             IDS_ASH_STATUS_TRAY_BATTERY_FULL));
159   } else {
160     status_label_->SetText(
161         l10n_util::GetStringFUTF16(
162             IDS_ASH_STATUS_TRAY_BATTERY_PERCENT,
163             base::IntToString16(status.GetRoundedBatteryPercent())));
164   }
165 
166   const base::TimeDelta time = status.IsBatteryCharging() ?
167       status.GetBatteryTimeToFull() : status.GetBatteryTimeToEmpty();
168 
169   if (status.IsUsbChargerConnected()) {
170     time_label_->SetText(
171         ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
172             IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE));
173   } else if (status.IsBatteryTimeBeingCalculated()) {
174     time_label_->SetText(
175         ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
176             IDS_ASH_STATUS_TRAY_BATTERY_CALCULATING));
177   } else if (PowerStatus::ShouldDisplayBatteryTime(time) &&
178              !status.IsBatteryDischargingOnLinePower()) {
179     int hour = 0, min = 0;
180     PowerStatus::SplitTimeIntoHoursAndMinutes(time, &hour, &min);
181     if (status.IsBatteryCharging()) {
182       time_label_->SetText(
183           l10n_util::GetStringFUTF16(
184               IDS_ASH_STATUS_TRAY_BATTERY_TIME_UNTIL_FULL,
185               base::IntToString16(hour),
186               base::IntToString16(min)));
187     } else {
188       // This is a low battery warning prompting the user in minutes.
189       time_label_->SetText(ui::TimeFormat::TimeRemaining(
190           base::TimeDelta::FromMinutes(hour * 60 + min)));
191     }
192   } else {
193     time_label_->SetText(base::string16());
194   }
195 }
196 
ChildPreferredSizeChanged(views::View * child)197 void PowerStatusView::ChildPreferredSizeChanged(views::View* child) {
198   PreferredSizeChanged();
199 }
200 
GetPreferredSize()201 gfx::Size PowerStatusView::GetPreferredSize() {
202   gfx::Size size = views::View::GetPreferredSize();
203   return gfx::Size(size.width(), kTrayPopupItemHeight);
204 }
205 
GetHeightForWidth(int width)206 int PowerStatusView::GetHeightForWidth(int width) {
207   return kTrayPopupItemHeight;
208 }
209 
Layout()210 void PowerStatusView::Layout() {
211   views::View::Layout();
212 
213   // Move the time_status_label_ closer to percentage_label_.
214   if (percentage_label_ && time_status_label_ &&
215       percentage_label_->visible() && time_status_label_->visible()) {
216     time_status_label_->SetX(percentage_label_->bounds().right() + 1);
217   }
218 }
219 
220 }  // namespace internal
221 }  // namespace ash
222