Index: ash/system/chromeos/tray_display.cc |
diff --git a/ash/system/chromeos/tray_display.cc b/ash/system/chromeos/tray_display.cc |
index 84f53692df06a6b9727ffffcd058a4fb1d313f13..392f1dbf09285aef8348dbba722a69bd0a43e588 100644 |
--- a/ash/system/chromeos/tray_display.cc |
+++ b/ash/system/chromeos/tray_display.cc |
@@ -6,33 +6,131 @@ |
#include "ash/display/display_controller.h" |
#include "ash/display/display_manager.h" |
-#include "ash/screen_ash.h" |
#include "ash/shell.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" |
#include "ash/system/tray/tray_constants.h" |
+#include "ash/system/tray/tray_notification_view.h" |
#include "base/chromeos/chromeos_version.h" |
#include "base/utf_string_conversions.h" |
-#include "chromeos/display/output_configurator.h" |
#include "grit/ash_resources.h" |
#include "grit/ash_strings.h" |
-#include "ui/aura/env.h" |
#include "ui/base/l10n/l10n_util.h" |
#include "ui/base/resource/resource_bundle.h" |
-#include "ui/base/x/x11_util.h" |
-#include "ui/gfx/image/image.h" |
-#include "ui/views/controls/image_view.h" |
#include "ui/views/controls/label.h" |
#include "ui/views/layout/box_layout.h" |
namespace ash { |
namespace internal { |
+namespace { |
-class DisplayView : public ash::internal::ActionableView { |
+TrayDisplayMode GetCurrentTrayDisplayMode() { |
+ DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
+ if (display_manager->GetNumDisplays() > 1) |
+ return TRAY_DISPLAY_EXTENDED; |
+ |
+ if (display_manager->IsMirrored()) |
+ return TRAY_DISPLAY_MIRRORED; |
+ |
+ int64 first_id = display_manager->first_display_id(); |
+ if (display_manager->HasInternalDisplay() && |
+ !display_manager->IsInternalDisplayId(first_id)) { |
+ return TRAY_DISPLAY_DOCKED; |
+ } |
+ |
+ return TRAY_DISPLAY_SINGLE; |
+} |
+ |
+// Returns the name of the currently connected external display. |
+base::string16 GetExternalDisplayName() { |
+ DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
+ int64 external_id = display_manager->mirrored_display().id(); |
+ |
+ if (external_id == gfx::Display::kInvalidDisplayID) { |
+ int64 internal_display_id = gfx::Display::InternalDisplayId(); |
+ for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { |
+ int64 id = display_manager->GetDisplayAt(i)->id(); |
+ if (id != internal_display_id) { |
+ external_id = id; |
+ break; |
+ } |
+ } |
+ } |
+ 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: |
- explicit DisplayView(user::LoginStatus login_status) |
+ DisplayViewBase(user::LoginStatus login_status) |
: login_status_(login_status) { |
+ label_ = new views::Label(); |
+ label_->SetMultiLine(true); |
+ label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
+ } |
+ |
+ virtual ~DisplayViewBase() { |
+ } |
+ |
+ 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(); |
+ } |
+ } |
+ |
+ 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; |
+ } |
+ return true; |
+ } |
+ |
+ views::Label* label() { return label_; } |
+ |
+ private: |
+ user::LoginStatus login_status_; |
+ views::Label* label_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(DisplayViewBase); |
+}; |
+ |
+} // namespace |
+ |
+class DisplayView : public DisplayViewBase, |
+ public ash::internal::ActionableView { |
+ public: |
+ explicit DisplayView(user::LoginStatus login_status) |
+ : DisplayViewBase(login_status) { |
SetLayoutManager(new |
views::BoxLayout(views::BoxLayout::kHorizontal, |
ash::kTrayPopupPaddingHorizontal, 0, |
@@ -44,126 +142,111 @@ class DisplayView : public ash::internal::ActionableView { |
image_->SetImage( |
bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY).ToImageSkia()); |
AddChildView(image_); |
- label_ = new views::Label(); |
- label_->SetMultiLine(true); |
- label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
- AddChildView(label_); |
+ AddChildView(label()); |
Update(); |
} |
virtual ~DisplayView() {} |
void Update() { |
- DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
- if (display_manager->num_connected_displays() == 1) { |
- // TODO(oshima|mukai): Support single display mode for overscan alignment. |
- SetVisible(false); |
- return; |
- } |
- SetVisible(true); |
- if (display_manager->IsMirrored()) { |
- label_->SetText(l10n_util::GetStringFUTF16( |
- IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetExternalDisplayName())); |
- } else { |
- label_->SetText(l10n_util::GetStringFUTF16( |
- IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, GetExternalDisplayName())); |
- } |
- } |
- |
- chromeos::OutputState InferOutputState() const { |
- return Shell::GetScreen()->GetNumDisplays() == 1 ? |
- chromeos::STATE_SINGLE : chromeos::STATE_DUAL_EXTENDED; |
+ SetVisible(UpdateLabelText()); |
} |
private: |
- // Returns the name of the currently connected external display. |
- base::string16 GetExternalDisplayName() const { |
- DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
- int64 external_id = display_manager->mirrored_display().id(); |
- |
- if (external_id == gfx::Display::kInvalidDisplayID) { |
- int64 internal_display_id = gfx::Display::InternalDisplayId(); |
- int64 first_display_id = display_manager->first_display_id(); |
- for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { |
- int64 id = display_manager->GetDisplayAt(i)->id(); |
- if (id != internal_display_id && id != first_display_id) { |
- external_id = id; |
- break; |
- } |
- } |
- } |
- if (external_id != gfx::Display::kInvalidDisplayID) |
- return UTF8ToUTF16(display_manager->GetDisplayNameForId(external_id)); |
- return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); |
- } |
- |
// Overridden from ActionableView. |
virtual bool PerformAction(const ui::Event& event) OVERRIDE { |
- 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(); |
- } |
- |
+ OpenSettings(); |
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 { |
+ public: |
+ DisplayNotificationView(user::LoginStatus login_status, |
+ TrayDisplay* tray_item) |
+ : DisplayViewBase(login_status), |
+ TrayNotificationView(tray_item, IDR_AURA_UBER_TRAY_DISPLAY) { |
+ InitView(label()); |
+ StartAutoCloseTimer(kTrayPopupAutoCloseDelayForTextInSeconds); |
+ Update(); |
+ } |
+ |
+ virtual ~DisplayNotificationView() {} |
+ |
+ void Update() { |
+ if (UpdateLabelText()) |
+ RestartAutoCloseTimer(); |
+ else |
+ owner()->HideNotificationView(); |
+ } |
+ |
+ // Overridden from TrayNotificationView: |
+ virtual void OnClickAction() OVERRIDE { |
+ OpenSettings(); |
+ } |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(DisplayNotificationView); |
+}; |
+ |
TrayDisplay::TrayDisplay(SystemTray* system_tray) |
: SystemTrayItem(system_tray), |
- default_(NULL) { |
- Shell::GetScreen()->AddObserver(this); |
- Shell::GetInstance()->output_configurator()->AddObserver(this); |
+ default_(NULL), |
+ notification_(NULL), |
+ current_mode_(GetCurrentTrayDisplayMode()) { |
+ Shell::GetInstance()->display_controller()->AddObserver(this); |
} |
TrayDisplay::~TrayDisplay() { |
- Shell::GetScreen()->RemoveObserver(this); |
- Shell::GetInstance()->output_configurator()->RemoveObserver(this); |
+ Shell::GetInstance()->display_controller()->RemoveObserver(this); |
} |
views::View* TrayDisplay::CreateDefaultView(user::LoginStatus status) { |
+ DCHECK(default_ == NULL); |
default_ = new DisplayView(status); |
return default_; |
} |
-void TrayDisplay::DestroyDefaultView() { |
- default_ = NULL; |
+views::View* TrayDisplay::CreateNotificationView(user::LoginStatus status) { |
+ DCHECK(notification_ == NULL); |
+ notification_ = new DisplayNotificationView(status, this); |
+ return notification_; |
} |
-void TrayDisplay::OnDisplayBoundsChanged(const gfx::Display& display) { |
- if (default_) |
- default_->Update(); |
+void TrayDisplay::DestroyDefaultView() { |
+ default_ = NULL; |
} |
-void TrayDisplay::OnDisplayAdded(const gfx::Display& new_display) { |
- if (default_) |
- default_->Update(); |
+void TrayDisplay::DestroyNotificationView() { |
+ notification_ = NULL; |
} |
-void TrayDisplay::OnDisplayRemoved(const gfx::Display& old_display) { |
- if (default_) |
- default_->Update(); |
+bool TrayDisplay::ShouldShowLauncher() const { |
+ return false; |
} |
-#if defined(OS_CHROMEOS) |
-void TrayDisplay::OnDisplayModeChanged() { |
- if (default_) |
- default_->Update(); |
+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; |
} |
-#endif |
} // namespace internal |
} // namespace ash |