| 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 |