Chromium Code Reviews| Index: ash/system/chromeos/tray_display.cc |
| diff --git a/ash/system/chromeos/tray_display.cc b/ash/system/chromeos/tray_display.cc |
| index cf3ca84b80f8b5e85030f65b7962728daeb3c9c3..9d48be0db23ae18de49811acb0679f3fd705a05e 100644 |
| --- a/ash/system/chromeos/tray_display.cc |
| +++ b/ash/system/chromeos/tray_display.cc |
| @@ -24,26 +24,32 @@ namespace ash { |
| namespace internal { |
| namespace { |
| -TrayDisplayMode GetCurrentTrayDisplayMode() { |
| - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
| - if (display_manager->GetNumDisplays() > 1) |
| - return TRAY_DISPLAY_EXTENDED; |
| +DisplayManager* GetDisplayManager() { |
| + return Shell::GetInstance()->display_manager(); |
| +} |
| - if (display_manager->IsMirrored()) |
| - return TRAY_DISPLAY_MIRRORED; |
| +base::string16 GetDisplayName(int64 display_id) { |
| + return UTF8ToUTF16(GetDisplayManager()->GetDisplayNameForId(display_id)); |
| +} |
| - int64 first_id = display_manager->first_display_id(); |
| - if (display_manager->HasInternalDisplay() && |
| - !display_manager->IsInternalDisplayId(first_id)) { |
| - return TRAY_DISPLAY_DOCKED; |
| - } |
| +base::string16 GetDisplaySize(int64 display_id) { |
| + return UTF8ToUTF16( |
| + GetDisplayManager()->GetDisplayForId(display_id).size().ToString()); |
| +} |
| + |
| +bool ShouldShowResolution(int64 display_id) { |
| + if (!GetDisplayManager()->GetDisplayForId(display_id).is_valid()) |
| + return false; |
| - return TRAY_DISPLAY_SINGLE; |
| + const DisplayInfo& display_info = |
| + GetDisplayManager()->GetDisplayInfo(display_id); |
| + return display_info.rotation() != gfx::Display::ROTATE_0 || |
| + display_info.ui_scale() != 1.0f; |
| } |
| // Returns the name of the currently connected external display. |
| base::string16 GetExternalDisplayName() { |
| - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
| + DisplayManager* display_manager = GetDisplayManager(); |
| int64 external_id = display_manager->mirrored_display().id(); |
| if (external_id == gfx::Display::kInvalidDisplayID) { |
| @@ -56,80 +62,62 @@ base::string16 GetExternalDisplayName() { |
| } |
| } |
| } |
| - if (external_id != gfx::Display::kInvalidDisplayID) |
| - return UTF8ToUTF16(display_manager->GetDisplayNameForId(external_id)); |
| - return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); |
| -} |
| -class DisplayViewBase { |
| - public: |
| - DisplayViewBase(user::LoginStatus login_status) |
| - : login_status_(login_status) { |
| - label_ = new views::Label(); |
| - label_->SetMultiLine(true); |
| - label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| - } |
| + if (external_id == gfx::Display::kInvalidDisplayID) |
| + return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); |
| - virtual ~DisplayViewBase() { |
| - } |
| + // The external display name may have an annotation of "(width x height)" in |
| + // case that the display is rotated or its resolution is changed. |
| + base::string16 name = GetDisplayName(external_id); |
| + if (ShouldShowResolution(external_id)) |
| + name += UTF8ToUTF16(" (") + GetDisplaySize(external_id) + UTF8ToUTF16(")"); |
|
oshima
2013/06/19 18:20:31
Any RTL issue here? (I think it's ok, but just dou
Jun Mukai
2013/06/19 23:42:35
looks okay to me
|
| - protected: |
| - void OpenSettings() { |
| - if (login_status_ == ash::user::LOGGED_IN_USER || |
| - login_status_ == ash::user::LOGGED_IN_OWNER || |
| - login_status_ == ash::user::LOGGED_IN_GUEST) { |
| - ash::Shell::GetInstance()->system_tray_delegate()->ShowDisplaySettings(); |
| + return name; |
| +} |
| + |
| +base::string16 GetTrayDisplayMessage() { |
| + DisplayManager* display_manager = GetDisplayManager(); |
| + if (display_manager->GetNumDisplays() > 1) { |
| + if (GetDisplayManager()->HasInternalDisplay()) { |
| + return l10n_util::GetStringFUTF16( |
| + IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, GetExternalDisplayName()); |
| } |
| + return l10n_util::GetStringUTF16( |
| + IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL); |
| } |
| - bool UpdateLabelText() { |
| - switch (GetCurrentTrayDisplayMode()) { |
| - case TRAY_DISPLAY_SINGLE: |
| - // TODO(oshima|mukai): Support single display mode for overscan |
| - // alignment. |
| - return false; |
| - case TRAY_DISPLAY_EXTENDED: |
| - if (Shell::GetInstance()->display_manager()->HasInternalDisplay()) { |
| - label_->SetText(l10n_util::GetStringFUTF16( |
| - IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, GetExternalDisplayName())); |
| - } else { |
| - label_->SetText(l10n_util::GetStringUTF16( |
| - IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL)); |
| - } |
| - break; |
| - case TRAY_DISPLAY_MIRRORED: |
| - if (Shell::GetInstance()->display_manager()->HasInternalDisplay()) { |
| - label_->SetText(l10n_util::GetStringFUTF16( |
| - IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetExternalDisplayName())); |
| - } else { |
| - label_->SetText(l10n_util::GetStringUTF16( |
| - IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING_NO_INTERNAL)); |
| - } |
| - break; |
| - case TRAY_DISPLAY_DOCKED: |
| - label_->SetText(l10n_util::GetStringUTF16( |
| - IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED)); |
| - break; |
| + if (display_manager->IsMirrored()) { |
| + if (GetDisplayManager()->HasInternalDisplay()) { |
| + return l10n_util::GetStringFUTF16( |
| + IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetExternalDisplayName()); |
| } |
| - return true; |
| + return l10n_util::GetStringUTF16( |
| + IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING_NO_INTERNAL); |
| } |
| - views::Label* label() { return label_; } |
| + int64 first_id = display_manager->first_display_id(); |
| + if (display_manager->HasInternalDisplay() && |
| + !display_manager->IsInternalDisplayId(first_id)) { |
| + return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED); |
| + } |
| - private: |
| - user::LoginStatus login_status_; |
| - views::Label* label_; |
| + return base::string16(); |
| +} |
| - DISALLOW_COPY_AND_ASSIGN(DisplayViewBase); |
| -}; |
| +void OpenSettings(user::LoginStatus login_status) { |
| + if (login_status == ash::user::LOGGED_IN_USER || |
| + login_status == ash::user::LOGGED_IN_OWNER || |
| + login_status == ash::user::LOGGED_IN_GUEST) { |
| + ash::Shell::GetInstance()->system_tray_delegate()->ShowDisplaySettings(); |
| + } |
| +} |
| } // namespace |
| -class DisplayView : public DisplayViewBase, |
| - public ash::internal::ActionableView { |
| +class DisplayView : public ash::internal::ActionableView { |
| public: |
| explicit DisplayView(user::LoginStatus login_status) |
| - : DisplayViewBase(login_status) { |
| + : login_status_(login_status) { |
| SetLayoutManager(new |
| views::BoxLayout(views::BoxLayout::kHorizontal, |
| ash::kTrayPopupPaddingHorizontal, 0, |
| @@ -141,70 +129,109 @@ class DisplayView : public DisplayViewBase, |
| image_->SetImage( |
| bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY).ToImageSkia()); |
| AddChildView(image_); |
| - AddChildView(label()); |
| + |
| + label_ = new views::Label(); |
| + label_->SetMultiLine(true); |
| + label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| + AddChildView(label_); |
| Update(); |
| } |
| virtual ~DisplayView() {} |
| void Update() { |
| - SetVisible(UpdateLabelText()); |
| + base::string16 message = GetTrayDisplayMessage(); |
| + if (message.empty()) |
| + message = GetInternalDisplayInfo(); |
| + SetVisible(!message.empty()); |
| + label_->SetText(message); |
| } |
| private: |
| + base::string16 GetInternalDisplayInfo() const { |
| + int64 first_id = GetDisplayManager()->first_display_id(); |
| + if (!ShouldShowResolution(first_id)) |
| + return base::string16(); |
| + |
| + return l10n_util::GetStringFUTF16( |
| + IDS_ASH_STATUS_TRAY_DISPLAY_SINGLE_DISPLAY, |
| + GetDisplayName(first_id), |
| + GetDisplaySize(first_id)); |
| + } |
| + |
| // Overridden from ActionableView. |
| virtual bool PerformAction(const ui::Event& event) OVERRIDE { |
| - OpenSettings(); |
| + OpenSettings(login_status_); |
| return true; |
| } |
| virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE { |
| int label_max_width = bounds().width() - kTrayPopupPaddingHorizontal * 2 - |
| kTrayPopupPaddingBetweenItems - image_->GetPreferredSize().width(); |
| - label()->SizeToFit(label_max_width); |
| + label_->SizeToFit(label_max_width); |
| PreferredSizeChanged(); |
| } |
| + // Overridden from views::View. |
| + virtual bool GetTooltipText(const gfx::Point& p, |
| + string16* tooltip) const OVERRIDE { |
| + base::string16 tray_message = GetTrayDisplayMessage(); |
| + base::string16 internal_message = GetInternalDisplayInfo(); |
| + if (tray_message.empty() && internal_message.empty()) |
| + return false; |
| + |
| + *tooltip = tray_message + base::string16(1, '\n') + internal_message; |
|
oshima
2013/06/19 18:20:31
RTL?
Jun Mukai
2013/06/19 23:42:35
linebreak won't suffer from RTL issue.
|
| + return true; |
| + } |
| + |
| + user::LoginStatus login_status_; |
| views::ImageView* image_; |
| + views::Label* label_; |
| DISALLOW_COPY_AND_ASSIGN(DisplayView); |
| }; |
| -class DisplayNotificationView : public DisplayViewBase, |
| - public TrayNotificationView { |
| +class DisplayNotificationView : public TrayNotificationView { |
| public: |
| DisplayNotificationView(user::LoginStatus login_status, |
| - TrayDisplay* tray_item) |
| - : DisplayViewBase(login_status), |
| - TrayNotificationView(tray_item, IDR_AURA_UBER_TRAY_DISPLAY) { |
| - InitView(label()); |
| + TrayDisplay* tray_item, |
| + const base::string16& message) |
| + : TrayNotificationView(tray_item, IDR_AURA_UBER_TRAY_DISPLAY), |
| + login_status_(login_status) { |
| StartAutoCloseTimer(kTrayPopupAutoCloseDelayForTextInSeconds); |
| - Update(); |
| + Update(message); |
| } |
| virtual ~DisplayNotificationView() {} |
| - void Update() { |
| - if (UpdateLabelText()) |
| - RestartAutoCloseTimer(); |
| - else |
| + void Update(const base::string16& message) { |
| + if (message.empty()) { |
| owner()->HideNotificationView(); |
| + } else { |
| + views::Label* label = new views::Label(message); |
| + label->SetMultiLine(true); |
| + label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| + UpdateView(label); |
| + RestartAutoCloseTimer(); |
| + } |
| } |
| // Overridden from TrayNotificationView: |
| virtual void OnClickAction() OVERRIDE { |
| - OpenSettings(); |
| + OpenSettings(login_status_); |
| } |
| private: |
| + user::LoginStatus login_status_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(DisplayNotificationView); |
| }; |
| TrayDisplay::TrayDisplay(SystemTray* system_tray) |
| : SystemTrayItem(system_tray), |
| default_(NULL), |
| - notification_(NULL), |
| - current_mode_(GetCurrentTrayDisplayMode()) { |
| + notification_(NULL) { |
| + current_message_ = GetDisplayMessageForNotification(); |
| Shell::GetInstance()->display_controller()->AddObserver(this); |
| } |
| @@ -212,6 +239,39 @@ TrayDisplay::~TrayDisplay() { |
| Shell::GetInstance()->display_controller()->RemoveObserver(this); |
| } |
| +base::string16 TrayDisplay::GetDisplayMessageForNotification() { |
| + DisplayManager* display_manager = GetDisplayManager(); |
| + std::map<int64, DisplayInfo> old_info; |
| + old_info.swap(display_info_); |
| + for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { |
| + int64 id = display_manager->GetDisplayAt(i)->id(); |
| + display_info_[id] = display_manager->GetDisplayInfo(id); |
| + } |
| + |
| + if (display_info_.size() == old_info.size()) { |
| + for (std::map<int64, DisplayInfo>::const_iterator iter = |
| + display_info_.begin(); iter != display_info_.end(); ++iter) { |
| + std::map<int64, DisplayInfo>::const_iterator old_iter = |
| + old_info.find(iter->first); |
| + if (old_iter == old_info.end()) |
| + break; |
| + |
| + if (iter->second.ui_scale() != old_iter->second.ui_scale()) { |
| + return l10n_util::GetStringFUTF16( |
| + IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED, |
| + GetDisplayName(iter->first), |
| + GetDisplaySize(iter->first)); |
| + } |
| + if (iter->second.rotation() != old_iter->second.rotation()) { |
| + return l10n_util::GetStringFUTF16( |
| + IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED, GetDisplayName(iter->first)); |
| + } |
| + } |
| + } |
| + |
| + return GetTrayDisplayMessage(); |
| +} |
| + |
| views::View* TrayDisplay::CreateDefaultView(user::LoginStatus status) { |
| DCHECK(default_ == NULL); |
| default_ = new DisplayView(status); |
| @@ -220,7 +280,7 @@ views::View* TrayDisplay::CreateDefaultView(user::LoginStatus status) { |
| views::View* TrayDisplay::CreateNotificationView(user::LoginStatus status) { |
| DCHECK(notification_ == NULL); |
| - notification_ = new DisplayNotificationView(status, this); |
| + notification_ = new DisplayNotificationView(status, this, current_message_); |
| return notification_; |
| } |
| @@ -237,14 +297,13 @@ bool TrayDisplay::ShouldShowLauncher() const { |
| } |
| void TrayDisplay::OnDisplayConfigurationChanged() { |
| - TrayDisplayMode new_mode = GetCurrentTrayDisplayMode(); |
| - if (current_mode_ != new_mode && new_mode != TRAY_DISPLAY_SINGLE) { |
| - if (notification_) |
| - notification_->Update(); |
| - else |
| - ShowNotificationView(); |
| - } |
| - current_mode_ = new_mode; |
| + // TODO(mukai): do not show the notification when the configuration changed |
| + // due to the user operation on display settings page. |
| + current_message_ = GetDisplayMessageForNotification(); |
| + if (notification_) |
| + notification_->Update(current_message_); |
| + else if (!current_message_.empty()) |
| + ShowNotificationView(); |
| } |
| } // namespace internal |