diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-02 18:30:50 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-02 18:30:50 +0000 |
commit | f7f06ea18c6c20546b6dbcebd0b1cc4527b057c5 (patch) | |
tree | 1700be50abbbc6f32f29e8eb12edcdc251ef8d38 /ash | |
parent | 958068f9967b2b1a715030755ac175f467acea37 (diff) | |
download | chromium_src-f7f06ea18c6c20546b6dbcebd0b1cc4527b057c5.zip chromium_src-f7f06ea18c6c20546b6dbcebd0b1cc4527b057c5.tar.gz chromium_src-f7f06ea18c6c20546b6dbcebd0b1cc4527b057c5.tar.bz2 |
ash uber tray: Add entry for power and date.
BUG=110130
TEST=none
Review URL: https://chromiumcodereview.appspot.com/9562008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124690 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/ash.gyp | 5 | ||||
-rw-r--r-- | ash/shell.cc | 5 | ||||
-rw-r--r-- | ash/shell.h | 7 | ||||
-rw-r--r-- | ash/system/power/power_status_controller.h | 21 | ||||
-rw-r--r-- | ash/system/power/power_supply_status.cc | 44 | ||||
-rw-r--r-- | ash/system/power/power_supply_status.h | 33 | ||||
-rw-r--r-- | ash/system/power/tray_power_date.cc | 296 | ||||
-rw-r--r-- | ash/system/power/tray_power_date.h | 51 | ||||
-rw-r--r-- | ash/system/tray/system_tray.cc | 6 |
9 files changed, 465 insertions, 3 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp index a0116b6..7a7402b 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -111,6 +111,11 @@ 'system/brightness/brightness_control_delegate.h', 'system/brightness/tray_brightness.cc', 'system/brightness/tray_brightness.h', + 'system/power/power_status_controller.h', + 'system/power/power_supply_status.cc', + 'system/power/power_supply_status.h', + 'system/power/tray_power_date.cc', + 'system/power/tray_power_date.h', 'system/settings/tray_settings.cc', 'system/settings/tray_settings.h', 'system/tray/system_tray.cc', diff --git a/ash/shell.cc b/ash/shell.cc index 651068f..519c9ee 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -18,6 +18,8 @@ #include "ash/system/audio/tray_volume.h" #include "ash/system/brightness/tray_brightness.h" #include "ash/system/settings/tray_settings.h" +#include "ash/system/power/power_status_controller.h" +#include "ash/system/power/tray_power_date.h" #include "ash/system/tray/system_tray_delegate.h" #include "ash/system/tray/system_tray.h" #include "ash/system/tray_user.h" @@ -427,10 +429,13 @@ void Shell::Init() { internal::TrayVolume* tray_volume = new internal::TrayVolume(); internal::TrayBrightness* tray_brightness = new internal::TrayBrightness(); + internal::TrayPowerDate* tray_power_date = new internal::TrayPowerDate(); audio_controller_ = tray_volume; brightness_controller_ = tray_brightness; + power_status_controller_ = tray_power_date; tray_->AddTrayItem(new internal::TrayUser()); + tray_->AddTrayItem(tray_power_date); tray_->AddTrayItem(tray_volume); tray_->AddTrayItem(tray_brightness); tray_->AddTrayItem(new internal::TraySettings()); diff --git a/ash/shell.h b/ash/shell.h index 40d5e20..1ef873cd 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -43,6 +43,7 @@ class BrightnessController; class Launcher; class NestedDispatcherController; class PowerButtonController; +class PowerStatusController; class ShellDelegate; class SystemTrayDelegate; class SystemTray; @@ -198,6 +199,9 @@ class ASH_EXPORT Shell { BrightnessController* brightness_controller() const { return brightness_controller_; } + PowerStatusController* power_status_controller() const { + return power_status_controller_; + } ShellDelegate* delegate() { return delegate_.get(); } SystemTrayDelegate* tray_delegate() { return tray_delegate_.get(); } @@ -284,9 +288,10 @@ class ASH_EXPORT Shell { scoped_ptr<WindowCycleController> window_cycle_controller_; scoped_ptr<internal::FocusCycler> focus_cycler_; - // The audio and brightness controllers are not owner by the shell. + // These controllers are not owned by the shell. AudioController* audio_controller_; BrightnessController* brightness_controller_; + PowerStatusController* power_status_controller_; // An event filter that pre-handles all key events to send them to an IME. scoped_ptr<internal::InputMethodEventFilter> input_method_filter_; diff --git a/ash/system/power/power_status_controller.h b/ash/system/power/power_status_controller.h new file mode 100644 index 0000000..877349c --- /dev/null +++ b/ash/system/power/power_status_controller.h @@ -0,0 +1,21 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_SYSTEM_POWER_POWER_STATUS_CONTROLLER_H_ +#define ASH_SYSTEM_POWER_POWER_STATUS_CONTROLLER_H_ + +namespace ash { + +struct PowerSupplyStatus; + +class PowerStatusController { + public: + virtual ~PowerStatusController() {} + + virtual void OnPowerStatusChanged(const PowerSupplyStatus& status) = 0; +}; + +}; + +#endif // ASH_SYSTEM_POWER_POWER_STATUS_CONTROLLER_H_ diff --git a/ash/system/power/power_supply_status.cc b/ash/system/power/power_supply_status.cc new file mode 100644 index 0000000..d1ad5dc --- /dev/null +++ b/ash/system/power/power_supply_status.cc @@ -0,0 +1,44 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/system/power/power_supply_status.h" + +#include "base/format_macros.h" +#include "base/stringprintf.h" + +namespace ash { + +PowerSupplyStatus::PowerSupplyStatus() + : line_power_on(false), + battery_is_present(false), + battery_is_full(false), + battery_seconds_to_empty(0), + battery_seconds_to_full(0), + battery_percentage(0) { +} + +std::string PowerSupplyStatus::ToString() const { + std::string result; + base::StringAppendF(&result, + "line_power_on = %s ", + line_power_on ? "true" : "false"); + base::StringAppendF(&result, + "battery_is_present = %s ", + battery_is_present ? "true" : "false"); + base::StringAppendF(&result, + "battery_is_full = %s ", + battery_is_full ? "true" : "false"); + base::StringAppendF(&result, + "battery_percentage = %f ", + battery_percentage); + base::StringAppendF(&result, + "battery_seconds_to_empty = %"PRId64" ", + battery_seconds_to_empty); + base::StringAppendF(&result, + "battery_seconds_to_full = %"PRId64" ", + battery_seconds_to_full); + return result; +} + +} // namespace ash diff --git a/ash/system/power/power_supply_status.h b/ash/system/power/power_supply_status.h new file mode 100644 index 0000000..c70101b --- /dev/null +++ b/ash/system/power/power_supply_status.h @@ -0,0 +1,33 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_SYSTEM_POWER_POWER_SUPPLY_STATUS_H_ +#define ASH_SYSTEM_POWER_POWER_SUPPLY_STATUS_H_ + +#include <string> + +#include "ash/ash_export.h" +#include "base/basictypes.h" + +namespace ash { + +struct ASH_EXPORT PowerSupplyStatus { + bool line_power_on; + + bool battery_is_present; + bool battery_is_full; + + // Time in seconds until the battery is empty or full, 0 for unknown. + int64 battery_seconds_to_empty; + int64 battery_seconds_to_full; + + double battery_percentage; + + PowerSupplyStatus(); + std::string ToString() const; +}; + +} // namespace ash + +#endif // ASH_SYSTEM_POWER_POWER_SUPPLY_STATUS_H_ diff --git a/ash/system/power/tray_power_date.cc b/ash/system/power/tray_power_date.cc new file mode 100644 index 0000000..15a0a22 --- /dev/null +++ b/ash/system/power/tray_power_date.cc @@ -0,0 +1,296 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/system/power/tray_power_date.h" + +#include "ash/shell.h" +#include "ash/system/power/power_supply_status.h" +#include "ash/system/tray/system_tray_delegate.h" +#include "base/i18n/time_formatting.h" +#include "base/stringprintf.h" +#include "base/time.h" +#include "base/timer.h" +#include "base/utf_string_conversions.h" +#include "grit/ui_resources.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkRect.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/image/image.h" +#include "ui/gfx/size.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/controls/button/text_button.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/view.h" +#include "unicode/datefmt.h" +#include "unicode/fieldpos.h" +#include "unicode/fmtable.h" + +namespace ash { +namespace internal { + +namespace { +// Width and height of battery images. +const int kBatteryImageHeight = 26; +const int kBatteryImageWidth = 24; +// Number of different power states. +const int kNumPowerImages = 20; +// Amount of slop to add into the timer to make sure we're into the next minute +// when the timer goes off. +const int kTimerSlopSeconds = 1; + +string16 FormatNicely(const base::Time& time) { + icu::UnicodeString date_string; + + scoped_ptr<icu::DateFormat> formatter( + icu::DateFormat::createDateInstance(icu::DateFormat::kFull)); + icu::FieldPosition position; + position.setField(UDAT_DAY_OF_WEEK_FIELD); + formatter->format(static_cast<UDate>(time.ToDoubleT() * 1000), + date_string, + position); + icu::UnicodeString day = date_string.retainBetween(position.getBeginIndex(), + position.getEndIndex()); + + date_string.remove(); + formatter.reset( + icu::DateFormat::createDateInstance(icu::DateFormat::kMedium)); + formatter->format(static_cast<UDate>(time.ToDoubleT() * 1000), date_string); + + date_string += "\n"; + date_string += day; + + return string16(date_string.getBuffer(), + static_cast<size_t>(date_string.length())); +} + +} + +namespace tray { + +// This view is used for both the tray and the popup. +class DateView : public views::Label { + public: + enum TimeType { + TIME, + DATE + }; + + DateView(base::HourClockType hour_type, TimeType type) + : hour_type_(hour_type), + type_(type) { + UpdateText(); + } + + virtual ~DateView() { + timer_.Stop(); + } + + private: + void UpdateText() { + base::Time now = base::Time::Now(); + if (type_ == TIME) { + SetText(base::TimeFormatTimeOfDayWithHourClockType(now, hour_type_, + base::kDropAmPm)); + } else { + SetText(FormatNicely(now)); + } + + SetTooltipText(base::TimeFormatFriendlyDate(now)); + SchedulePaint(); + + // Try to set the timer to go off at the next change of the minute. We don't + // want to have the timer go off more than necessary since that will cause + // the CPU to wake up and consume power. + base::Time::Exploded exploded; + now.LocalExplode(&exploded); + + // Often this will be called at minute boundaries, and we'll actually want + // 60 seconds from now. + int seconds_left = 60 - exploded.second; + if (seconds_left == 0) + seconds_left = 60; + + // Make sure that the timer fires on the next minute. Without this, if it is + // called just a teeny bit early, then it will skip the next minute. + seconds_left += kTimerSlopSeconds; + + timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(seconds_left), this, + &DateView::UpdateText); + } + + // Overridden from views::View. + virtual void OnLocaleChanged() OVERRIDE { + UpdateText(); + } + + base::OneShotTimer<DateView> timer_; + base::HourClockType hour_type_; + TimeType type_; + + DISALLOW_COPY_AND_ASSIGN(DateView); +}; + +// This view is used only for the tray. +class PowerTrayView : public views::ImageView { + public: + PowerTrayView() { + UpdateImage(); + } + + virtual ~PowerTrayView() { + } + + void UpdatePowerStatus(const PowerSupplyStatus& status) { + supply_status_ = status; + // Sanitize. + if (supply_status_.battery_is_full) + supply_status_.battery_percentage = 100.0; + + UpdateImage(); + } + + private: + void UpdateImage() { + SkBitmap image; + gfx::Image all = ui::ResourceBundle::GetSharedInstance().GetImageNamed( + IDR_AURA_UBER_TRAY_POWER_SMALL); + + int image_index = 0; + if (supply_status_.battery_percentage >= 100) { + image_index = kNumPowerImages - 1; + } else if (!supply_status_.battery_is_present) { + image_index = kNumPowerImages; + } else { + image_index = static_cast<int> ( + supply_status_.battery_percentage / 100.0 * + (kNumPowerImages - 1)); + image_index = + std::max(std::min(image_index, kNumPowerImages - 2), 0); + } + + SkIRect region = SkIRect::MakeXYWH( + image_index * kBatteryImageWidth, + supply_status_.line_power_on ? 0 : kBatteryImageHeight, + kBatteryImageWidth, kBatteryImageHeight); + all.ToSkBitmap()->extractSubset(&image, region); + + SetImage(image); + } + + PowerSupplyStatus supply_status_; + + DISALLOW_COPY_AND_ASSIGN(PowerTrayView); +}; + +// This view is used only for the popup. +class PowerPopupView : public views::Label { + public: + PowerPopupView() { + SetHorizontalAlignment(ALIGN_RIGHT); + UpdateText(); + } + + virtual ~PowerPopupView() { + } + + void UpdatePowerStatus(const PowerSupplyStatus& status) { + supply_status_ = status; + // Sanitize. + if (supply_status_.battery_is_full) + supply_status_.battery_percentage = 100.0; + + UpdateText(); + } + + private: + void UpdateText() { + base::TimeDelta time = base::TimeDelta::FromSeconds( + supply_status_.line_power_on ? + supply_status_.battery_seconds_to_full : + supply_status_.battery_seconds_to_empty); + int hour = time.InHours(); + int min = (time - base::TimeDelta::FromHours(hour)).InMinutes(); + // TODO: Translation + SetText(ASCIIToUTF16(base::StringPrintf("Battery: %.0lf%%\n%dh%02dm", + supply_status_.battery_percentage, + hour, min))); + } + + PowerSupplyStatus supply_status_; + + DISALLOW_COPY_AND_ASSIGN(PowerPopupView); +}; + +} // namespace tray + +TrayPowerDate::TrayPowerDate() + : power_(NULL), + power_tray_(NULL) { +} + +TrayPowerDate::~TrayPowerDate() { +} + +views::View* TrayPowerDate::CreateTrayView() { + date_tray_.reset(new tray::DateView(base::k24HourClock, + tray::DateView::TIME)); + date_tray_->SetFont(date_tray_->font().DeriveFont(-1, gfx::Font::BOLD)); + date_tray_->SetAutoColorReadabilityEnabled(false); + date_tray_->SetEnabledColor(SK_ColorWHITE); + + power_tray_.reset(new tray::PowerTrayView()); + + views::View* container = new views::View; + container->SetLayoutManager(new views::BoxLayout( + views::BoxLayout::kHorizontal, 0, 0, 0)); + container->AddChildView(power_tray_.get()); + container->AddChildView(date_tray_.get()); + + return container; +} + +views::View* TrayPowerDate::CreateDefaultView() { + date_.reset(new tray::DateView(base::k24HourClock, + tray::DateView::DATE)); + power_.reset(new tray::PowerPopupView()); + + views::View* container = new views::View; + views::BoxLayout* layout = new + views::BoxLayout(views::BoxLayout::kHorizontal, 0, 10, 0); + layout->set_spread_blank_space(true); + container->SetLayoutManager(layout); + container->set_background(views::Background::CreateSolidBackground( + SkColorSetARGB(255, 240, 240, 240))); + container->AddChildView(date_.get()); + container->AddChildView(power_.get()); + return container; +} + +views::View* TrayPowerDate::CreateDetailedView() { + return NULL; +} + +void TrayPowerDate::DestroyTrayView() { + date_tray_.reset(); + power_tray_.reset(); +} + +void TrayPowerDate::DestroyDefaultView() { + date_.reset(); + power_.reset(); +} + +void TrayPowerDate::DestroyDetailedView() { +} + +void TrayPowerDate::OnPowerStatusChanged(const PowerSupplyStatus& status) { + power_tray_->UpdatePowerStatus(status); + if (power_.get()) + power_->UpdatePowerStatus(status); +} + +} // namespace internal +} // namespace ash diff --git a/ash/system/power/tray_power_date.h b/ash/system/power/tray_power_date.h new file mode 100644 index 0000000..5427149 --- /dev/null +++ b/ash/system/power/tray_power_date.h @@ -0,0 +1,51 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_SYSTEM_POWER_TRAY_POWER_DATE_H_ +#define ASH_SYSTEM_POWER_TRAY_POWER_DATE_H_ +#pragma once + +#include "ash/system/power/power_status_controller.h" +#include "ash/system/tray/system_tray_item.h" + +namespace ash { +namespace internal { + +namespace tray { +class DateView; +class PowerPopupView; +class PowerTrayView; +} + +class TrayPowerDate : public SystemTrayItem, + public PowerStatusController { + public: + TrayPowerDate(); + virtual ~TrayPowerDate(); + + private: + // Overridden from SystemTrayItem. + virtual views::View* CreateTrayView() OVERRIDE; + virtual views::View* CreateDefaultView() OVERRIDE; + virtual views::View* CreateDetailedView() OVERRIDE; + virtual void DestroyTrayView() OVERRIDE; + virtual void DestroyDefaultView() OVERRIDE; + virtual void DestroyDetailedView() OVERRIDE; + + // Overridden from PowerStatusController. + virtual void OnPowerStatusChanged(const PowerSupplyStatus& status) OVERRIDE; + + scoped_ptr<tray::DateView> date_; + scoped_ptr<tray::DateView> date_tray_; + + scoped_ptr<tray::PowerPopupView> power_; + scoped_ptr<tray::PowerTrayView> power_tray_; + + DISALLOW_COPY_AND_ASSIGN(TrayPowerDate); +}; + +} // namespace internal +} // namespace ash + +#endif // ASH_SYSTEM_POWER_TRAY_POWER_DATE_H_ diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc index dc4b13f..341dbc6 100644 --- a/ash/system/tray/system_tray.cc +++ b/ash/system/tray/system_tray.cc @@ -30,7 +30,7 @@ class SystemTrayBubble : public views::BubbleDelegateView { tray_(tray), items_(items), detailed_(detailed) { - set_margin(1); + set_margin(0); } virtual ~SystemTrayBubble() { @@ -77,7 +77,9 @@ SystemTray::SystemTray() : items_(), popup_(NULL) { SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, - 5, 10, 3)); + 5, 0, 3)); + set_background(views::Background::CreateSolidBackground( + SkColorSetARGB(127, 0, 0, 0))); } SystemTray::~SystemTray() { |