OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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_area_view.h" | 5 #include "chrome/browser/chromeos/status_area_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <dlfcn.h> |
8 | 9 |
9 #include "app/gfx/canvas.h" | 10 #include "app/gfx/canvas.h" |
10 #include "app/gfx/font.h" | 11 #include "app/gfx/font.h" |
11 #include "app/l10n_util.h" | 12 #include "app/l10n_util.h" |
12 #include "app/resource_bundle.h" | 13 #include "app/resource_bundle.h" |
13 #include "app/theme_provider.h" | 14 #include "app/theme_provider.h" |
| 15 #include "base/path_service.h" |
14 #include "base/string_util.h" | 16 #include "base/string_util.h" |
15 #include "base/time.h" | 17 #include "base/time.h" |
16 #include "base/timer.h" | 18 #include "base/timer.h" |
17 #include "chrome/app/chrome_dll_resource.h" | 19 #include "chrome/app/chrome_dll_resource.h" |
18 #include "chrome/browser/browser.h" | 20 #include "chrome/browser/browser.h" |
19 #include "chrome/browser/browser_window.h" | 21 #include "chrome/browser/browser_window.h" |
| 22 #include "chrome/common/chrome_paths.h" |
20 #include "chrome/browser/gtk/browser_window_gtk.h" | 23 #include "chrome/browser/gtk/browser_window_gtk.h" |
21 #include "chrome/browser/profile.h" | 24 #include "chrome/browser/profile.h" |
22 #include "grit/chromium_strings.h" | 25 #include "grit/chromium_strings.h" |
23 #include "grit/generated_resources.h" | 26 #include "grit/generated_resources.h" |
24 #include "grit/theme_resources.h" | 27 #include "grit/theme_resources.h" |
25 #include "views/controls/button/menu_button.h" | 28 #include "views/controls/button/menu_button.h" |
26 #include "views/controls/image_view.h" | 29 #include "views/controls/image_view.h" |
27 #include "views/controls/menu/menu.h" | 30 #include "views/controls/menu/menu.h" |
28 #include "views/controls/menu/simple_menu_model.h" | 31 #include "views/controls/menu/simple_menu_model.h" |
29 | 32 |
30 namespace { | 33 namespace { |
31 | 34 |
| 35 // The number of images representing the fullness of the battery. |
| 36 const int kNumBatteryImages = 8; |
| 37 |
32 // Number of pixels to separate adjacent status items. | 38 // Number of pixels to separate adjacent status items. |
33 const int kStatusItemSeparation = 1; | 39 const int kStatusItemSeparation = 1; |
34 | 40 |
35 class ClockView : public views::View { | 41 class ClockView : public views::View { |
36 public: | 42 public: |
37 ClockView(); | 43 ClockView(); |
38 virtual ~ClockView(); | 44 virtual ~ClockView(); |
39 | 45 |
40 // views::View* overrides. | 46 // views::View* overrides. |
41 virtual gfx::Size GetPreferredSize(); | 47 virtual gfx::Size GetPreferredSize(); |
(...skipping 12 matching lines...) Expand all Loading... |
54 | 60 |
55 DISALLOW_COPY_AND_ASSIGN(ClockView); | 61 DISALLOW_COPY_AND_ASSIGN(ClockView); |
56 }; | 62 }; |
57 | 63 |
58 // Amount of slop to add into the timer to make sure we're into the next minute | 64 // Amount of slop to add into the timer to make sure we're into the next minute |
59 // when the timer goes off. | 65 // when the timer goes off. |
60 const int kTimerSlopSeconds = 1; | 66 const int kTimerSlopSeconds = 1; |
61 | 67 |
62 ClockView::ClockView() | 68 ClockView::ClockView() |
63 : font_(ResourceBundle::GetSharedInstance().GetFont( | 69 : font_(ResourceBundle::GetSharedInstance().GetFont( |
64 ResourceBundle::BaseFont)) { | 70 ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD)) { |
65 SetNextTimer(); | 71 SetNextTimer(); |
66 } | 72 } |
67 | 73 |
68 ClockView::~ClockView() { | 74 ClockView::~ClockView() { |
69 } | 75 } |
70 | 76 |
71 gfx::Size ClockView::GetPreferredSize() { | 77 gfx::Size ClockView::GetPreferredSize() { |
72 return gfx::Size(40, 10); | 78 return gfx::Size(40, 12); |
73 } | 79 } |
74 | 80 |
75 void ClockView::Paint(gfx::Canvas* canvas) { | 81 void ClockView::Paint(gfx::Canvas* canvas) { |
76 base::Time now = base::Time::Now(); | 82 base::Time now = base::Time::Now(); |
77 base::Time::Exploded now_exploded; | 83 base::Time::Exploded now_exploded; |
78 now.LocalExplode(&now_exploded); | 84 now.LocalExplode(&now_exploded); |
| 85 int hour = now_exploded.hour % 12; |
| 86 if (hour == 0) |
| 87 hour = 12; |
79 | 88 |
80 std::wstring time_string = StringPrintf(L"%d:%02d", | 89 std::wstring time_string = StringPrintf(L"%d:%02d%lc", |
81 now_exploded.hour, | 90 hour, |
82 now_exploded.minute); | 91 now_exploded.minute, |
| 92 now_exploded.hour < 12 ? L'p' : L'p'); |
83 canvas->DrawStringInt(time_string, font_, SK_ColorWHITE, 0, 0, | 93 canvas->DrawStringInt(time_string, font_, SK_ColorWHITE, 0, 0, |
84 width(), height(), gfx::Canvas::TEXT_ALIGN_CENTER); | 94 width(), height(), gfx::Canvas::TEXT_ALIGN_CENTER); |
85 } | 95 } |
86 | 96 |
87 void ClockView::SetNextTimer() { | 97 void ClockView::SetNextTimer() { |
88 // Try to set the timer to go off at the next change of the minute. We don't | 98 // Try to set the timer to go off at the next change of the minute. We don't |
89 // want to have the timer go off more than necessary since that will cause | 99 // want to have the timer go off more than necessary since that will cause |
90 // the CPU to wake up and consume power. | 100 // the CPU to wake up and consume power. |
91 base::Time now = base::Time::Now(); | 101 base::Time now = base::Time::Now(); |
92 base::Time::Exploded exploded; | 102 base::Time::Exploded exploded; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 | 188 |
179 DISALLOW_COPY_AND_ASSIGN(OptionsMenuModel); | 189 DISALLOW_COPY_AND_ASSIGN(OptionsMenuModel); |
180 }; | 190 }; |
181 | 191 |
182 } // namespace | 192 } // namespace |
183 | 193 |
184 // Default to opening new tabs on the left. | 194 // Default to opening new tabs on the left. |
185 StatusAreaView::OpenTabsMode StatusAreaView::open_tabs_mode_ = | 195 StatusAreaView::OpenTabsMode StatusAreaView::open_tabs_mode_ = |
186 StatusAreaView::OPEN_TABS_ON_LEFT; | 196 StatusAreaView::OPEN_TABS_ON_LEFT; |
187 | 197 |
| 198 // static |
| 199 void* StatusAreaView::power_library_ = NULL; |
| 200 bool StatusAreaView::power_library_error_ = false; |
| 201 |
188 StatusAreaView::StatusAreaView(Browser* browser) | 202 StatusAreaView::StatusAreaView(Browser* browser) |
189 : browser_(browser), | 203 : browser_(browser), |
190 battery_view_(NULL), | 204 battery_view_(NULL), |
191 menu_view_(NULL) { | 205 menu_view_(NULL), |
| 206 power_status_connection_(NULL) { |
192 } | 207 } |
193 | 208 |
194 StatusAreaView::~StatusAreaView() { | 209 StatusAreaView::~StatusAreaView() { |
| 210 if (power_status_connection_) |
| 211 chromeos::DisconnectPowerStatus(power_status_connection_); |
195 } | 212 } |
196 | 213 |
197 void StatusAreaView::Init() { | 214 void StatusAreaView::Init() { |
198 ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance(); | 215 LoadPowerLibrary(); |
199 | 216 ThemeProvider* theme = browser_->profile()->GetThemeProvider(); |
200 // Battery. | |
201 battery_view_ = new views::ImageView; | |
202 battery_view_->SetImage( | |
203 resource_bundle.GetBitmapNamed(IDR_STATUSBAR_BATTERY)); | |
204 AddChildView(battery_view_); | |
205 | 217 |
206 // Clock. | 218 // Clock. |
207 AddChildView(new ClockView); | 219 AddChildView(new ClockView); |
208 | 220 |
| 221 // Battery. |
| 222 battery_view_ = new views::ImageView; |
| 223 battery_view_->SetImage(theme->GetBitmapNamed(IDR_STATUSBAR_BATTERY_UNKNOWN)); |
| 224 AddChildView(battery_view_); |
| 225 |
209 // Menu. | 226 // Menu. |
210 menu_view_ = new views::MenuButton(NULL, std::wstring(), this, false); | 227 menu_view_ = new views::MenuButton(NULL, std::wstring(), this, false); |
211 menu_view_->SetIcon(*resource_bundle.GetBitmapNamed(IDR_STATUSBAR_MENU)); | 228 menu_view_->SetIcon(*theme->GetBitmapNamed(IDR_STATUSBAR_MENU)); |
212 AddChildView(menu_view_); | 229 AddChildView(menu_view_); |
| 230 |
| 231 if (power_library_) { |
| 232 power_status_connection_ = chromeos::MonitorPowerStatus( |
| 233 StatusAreaView::PowerStatusChangedHandler, |
| 234 this); |
| 235 } |
213 } | 236 } |
214 | 237 |
215 gfx::Size StatusAreaView::GetPreferredSize() { | 238 gfx::Size StatusAreaView::GetPreferredSize() { |
216 int result_w = kStatusItemSeparation; // Left border. | 239 int result_w = kStatusItemSeparation; // Left border. |
217 int result_h = 0; | 240 int result_h = 0; |
218 for (int i = 0; i < GetChildViewCount(); i++) { | 241 for (int i = 0; i < GetChildViewCount(); i++) { |
219 gfx::Size cur_size = GetChildViewAt(i)->GetPreferredSize(); | 242 gfx::Size cur_size = GetChildViewAt(i)->GetPreferredSize(); |
220 result_w += cur_size.width() + kStatusItemSeparation; | 243 result_w += cur_size.width() + kStatusItemSeparation; |
221 result_h = std::max(result_h, cur_size.height()); | 244 result_h = std::max(result_h, cur_size.height()); |
222 } | 245 } |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 | 347 |
325 void StatusAreaView::ExecuteCommand(int command_id) { | 348 void StatusAreaView::ExecuteCommand(int command_id) { |
326 browser_->ExecuteCommand(command_id); | 349 browser_->ExecuteCommand(command_id); |
327 } | 350 } |
328 | 351 |
329 void StatusAreaView::RunMenu(views::View* source, const gfx::Point& pt, | 352 void StatusAreaView::RunMenu(views::View* source, const gfx::Point& pt, |
330 gfx::NativeView hwnd) { | 353 gfx::NativeView hwnd) { |
331 CreateAppMenu(); | 354 CreateAppMenu(); |
332 app_menu_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); | 355 app_menu_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); |
333 } | 356 } |
| 357 |
| 358 // static |
| 359 void StatusAreaView::LoadPowerLibrary() { |
| 360 if (power_library_) { |
| 361 // Already loaded. |
| 362 return; |
| 363 } |
| 364 |
| 365 if (power_library_error_) { |
| 366 // Error in previous load attempt. |
| 367 return; |
| 368 } |
| 369 |
| 370 FilePath path; |
| 371 if (PathService::Get(chrome::FILE_CHROMEOS_API, &path)) { |
| 372 power_library_ = dlopen(path.value().c_str(), RTLD_NOW); |
| 373 if (power_library_) { |
| 374 chromeos::LoadPower(power_library_); |
| 375 } else { |
| 376 power_library_error_ = true; |
| 377 char* error = dlerror(); |
| 378 if (error) { |
| 379 LOG(ERROR) << "Problem loading chromeos shared object: " << error; |
| 380 } |
| 381 } |
| 382 } |
| 383 } |
| 384 |
| 385 // static |
| 386 void StatusAreaView::PowerStatusChangedHandler( |
| 387 void* object, const chromeos::PowerStatus& status) { |
| 388 static_cast<StatusAreaView*>(object)->PowerStatusChanged(status); |
| 389 } |
| 390 |
| 391 void StatusAreaView::PowerStatusChanged(const chromeos::PowerStatus& status) { |
| 392 ThemeProvider* theme = browser_->profile()->GetThemeProvider(); |
| 393 int image_index; |
| 394 |
| 395 if (status.battery_state == chromeos::BATTERY_STATE_FULLY_CHARGED && |
| 396 status.line_power_on) { |
| 397 image_index = IDR_STATUSBAR_BATTERY_CHARGED; |
| 398 } else { |
| 399 image_index = status.line_power_on ? |
| 400 IDR_STATUSBAR_BATTERY_CHARGING_1 : |
| 401 IDR_STATUSBAR_BATTERY_DISCHARGING_1; |
| 402 double percentage = status.battery_percentage; |
| 403 int offset = floor(percentage / (100.0 / kNumBatteryImages)); |
| 404 // This can happen if the battery is 100% full. |
| 405 if (offset == kNumBatteryImages) |
| 406 offset--; |
| 407 image_index += offset; |
| 408 } |
| 409 battery_view_->SetImage(theme->GetBitmapNamed(image_index)); |
| 410 } |
OLD | NEW |