diff options
Diffstat (limited to 'ash/system/chromeos/tray_display.cc')
-rw-r--r-- | ash/system/chromeos/tray_display.cc | 286 |
1 files changed, 186 insertions, 100 deletions
diff --git a/ash/system/chromeos/tray_display.cc b/ash/system/chromeos/tray_display.cc index cf3ca84..484e0d2 100644 --- a/ash/system/chromeos/tray_display.cc +++ b/ash/system/chromeos/tray_display.cc @@ -7,6 +7,7 @@ #include "ash/display/display_controller.h" #include "ash/display/display_manager.h" #include "ash/shell.h" +#include "ash/system/tray/actionable_view.h" #include "ash/system/tray/fixed_sized_image_view.h" #include "ash/system/tray/system_tray.h" #include "ash/system/tray/system_tray_delegate.h" @@ -17,6 +18,7 @@ #include "grit/ash_strings.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/layout/box_layout.h" @@ -24,26 +26,34 @@ namespace ash { namespace internal { namespace { -TrayDisplayMode GetCurrentTrayDisplayMode() { - DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - if (display_manager->GetNumDisplays() > 1) - return TRAY_DISPLAY_EXTENDED; +bool display_notifications_disabled = false; - if (display_manager->IsMirrored()) - return TRAY_DISPLAY_MIRRORED; +DisplayManager* GetDisplayManager() { + return Shell::GetInstance()->display_manager(); +} - int64 first_id = display_manager->first_display_id(); - if (display_manager->HasInternalDisplay() && - !display_manager->IsInternalDisplayId(first_id)) { - return TRAY_DISPLAY_DOCKED; - } +base::string16 GetDisplayName(int64 display_id) { + return UTF8ToUTF16(GetDisplayManager()->GetDisplayNameForId(display_id)); +} + +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,82 +66,64 @@ 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(")"); - 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) { - SetLayoutManager(new - views::BoxLayout(views::BoxLayout::kHorizontal, + : login_status_(login_status) { + SetLayoutManager(new views::BoxLayout( + views::BoxLayout::kHorizontal, ash::kTrayPopupPaddingHorizontal, 0, ash::kTrayPopupPaddingBetweenItems)); @@ -141,70 +133,111 @@ 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); + } + + views::Label* label() { return label_; } + + // Overridden from views::View. + virtual bool GetTooltipText(const gfx::Point& p, + base::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 + ASCIIToUTF16("\n") + internal_message; + return true; } 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(); } + 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 +245,45 @@ TrayDisplay::~TrayDisplay() { Shell::GetInstance()->display_controller()->RemoveObserver(this); } +base::string16 TrayDisplay::GetDisplayMessageForNotification() { + DisplayManager* display_manager = GetDisplayManager(); + DisplayInfoMap 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); + } + + // Display is added or removed. Use the same message as the one in + // the system tray. + if (display_info_.size() != old_info.size()) + return GetTrayDisplayMessage(); + + for (DisplayInfoMap::const_iterator iter = display_info_.begin(); + iter != display_info_.end(); ++iter) { + DisplayInfoMap::const_iterator old_iter = old_info.find(iter->first); + // A display is removed and added at the same time. It won't happen + // in the actual environment, but falls back to the system tray's + // message just in case. + if (old_iter == old_info.end()) + return GetTrayDisplayMessage(); + + 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)); + } + } + + // Found nothing special + return base::string16(); +} + views::View* TrayDisplay::CreateDefaultView(user::LoginStatus status) { DCHECK(default_ == NULL); default_ = new DisplayView(status); @@ -220,7 +292,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 +309,28 @@ 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; + if (display_notifications_disabled) + return; + + // 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(); +} + +// static +void TrayDisplay::SetDisplayNotificationsDisabledForTest(bool disabled) { + display_notifications_disabled = disabled; +} + +base::string16 TrayDisplay::GetDefaultViewMessage() { + if (!default_ || !default_->visible()) + return base::string16(); + + return static_cast<DisplayView*>(default_)->label()->text(); } } // namespace internal |