Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / ash / system / chromeos / tray_display.cc
blob6a026a98e8026c05753fc12a2a02199e6371ae19
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/system/chromeos/tray_display.h"
7 #include "ash/display/display_controller.h"
8 #include "ash/display/display_manager.h"
9 #include "ash/screen_ash.h"
10 #include "ash/shell.h"
11 #include "ash/system/tray/fixed_sized_image_view.h"
12 #include "ash/system/tray/system_tray.h"
13 #include "ash/system/tray/system_tray_delegate.h"
14 #include "ash/system/tray/tray_constants.h"
15 #include "ash/system/tray/tray_views.h"
16 #include "base/chromeos/chromeos_version.h"
17 #include "base/utf_string_conversions.h"
18 #include "grit/ash_resources.h"
19 #include "grit/ash_strings.h"
20 #include "ui/aura/env.h"
21 #include "ui/base/l10n/l10n_util.h"
22 #include "ui/base/resource/resource_bundle.h"
23 #include "ui/gfx/image/image.h"
24 #include "ui/views/controls/image_view.h"
25 #include "ui/views/controls/label.h"
26 #include "ui/views/layout/box_layout.h"
28 #if defined(USE_X11)
29 #include "chromeos/display/output_configurator.h"
30 #include "ui/base/x/x11_util.h"
31 #endif
33 namespace ash {
34 namespace internal {
36 class DisplayView : public ash::internal::ActionableView {
37 public:
38 explicit DisplayView(user::LoginStatus login_status)
39 : login_status_(login_status) {
40 SetLayoutManager(new
41 views::BoxLayout(views::BoxLayout::kHorizontal,
42 ash::kTrayPopupPaddingHorizontal, 0,
43 ash::kTrayPopupPaddingBetweenItems));
45 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
46 image_ =
47 new ash::internal::FixedSizedImageView(0, ash::kTrayPopupItemHeight);
48 image_->SetImage(
49 bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY).ToImageSkia());
50 AddChildView(image_);
51 label_ = new views::Label();
52 label_->SetMultiLine(true);
53 label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
54 AddChildView(label_);
55 Update();
58 virtual ~DisplayView() {}
60 void Update() {
61 chromeos::OutputState state =
62 base::chromeos::IsRunningOnChromeOS() ?
63 Shell::GetInstance()->output_configurator()->output_state() :
64 InferOutputState();
65 switch (state) {
66 case chromeos::STATE_INVALID:
67 case chromeos::STATE_HEADLESS:
68 case chromeos::STATE_SINGLE:
69 SetVisible(false);
70 return;
71 case chromeos::STATE_DUAL_MIRROR:
72 label_->SetText(l10n_util::GetStringFUTF16(
73 IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetExternalDisplayName()));
74 SetVisible(true);
75 return;
76 case chromeos::STATE_DUAL_EXTENDED:
77 label_->SetText(l10n_util::GetStringFUTF16(
78 IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, GetExternalDisplayName()));
79 SetVisible(true);
80 return;
82 NOTREACHED() << "Unhandled state " << state;
85 chromeos::OutputState InferOutputState() const {
86 return Shell::GetScreen()->GetNumDisplays() == 1 ?
87 chromeos::STATE_SINGLE : chromeos::STATE_DUAL_EXTENDED;
90 private:
91 // Returns the name of the currently connected external display.
92 string16 GetExternalDisplayName() const {
93 DisplayManager* display_manager = Shell::GetInstance()->display_manager();
94 int64 external_id = display_manager->mirrored_display_id();
96 if (external_id == gfx::Display::kInvalidDisplayID) {
97 int64 internal_display_id = gfx::Display::InternalDisplayId();
98 int64 first_display_id = display_manager->first_display_id();
99 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
100 int64 id = display_manager->GetDisplayAt(i)->id();
101 if (id != internal_display_id && id != first_display_id) {
102 external_id = id;
103 break;
107 if (external_id != gfx::Display::kInvalidDisplayID)
108 return UTF8ToUTF16(display_manager->GetDisplayNameForId(external_id));
109 return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME);
112 // Overridden from ActionableView.
113 virtual bool PerformAction(const ui::Event& event) OVERRIDE {
114 if (login_status_ == ash::user::LOGGED_IN_USER ||
115 login_status_ == ash::user::LOGGED_IN_OWNER ||
116 login_status_ == ash::user::LOGGED_IN_GUEST) {
117 ash::Shell::GetInstance()->system_tray_delegate()->ShowDisplaySettings();
120 return true;
123 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE {
124 int label_max_width = bounds().width() - kTrayPopupPaddingHorizontal * 2 -
125 kTrayPopupPaddingBetweenItems - image_->GetPreferredSize().width();
126 label_->SizeToFit(label_max_width);
127 PreferredSizeChanged();
130 user::LoginStatus login_status_;
131 views::ImageView* image_;
132 views::Label* label_;
134 DISALLOW_COPY_AND_ASSIGN(DisplayView);
137 TrayDisplay::TrayDisplay(SystemTray* system_tray)
138 : SystemTrayItem(system_tray),
139 default_(NULL) {
140 Shell::GetScreen()->AddObserver(this);
141 Shell::GetInstance()->output_configurator()->AddObserver(this);
144 TrayDisplay::~TrayDisplay() {
145 Shell::GetScreen()->RemoveObserver(this);
146 Shell::GetInstance()->output_configurator()->RemoveObserver(this);
149 views::View* TrayDisplay::CreateDefaultView(user::LoginStatus status) {
150 default_ = new DisplayView(status);
151 return default_;
154 void TrayDisplay::DestroyDefaultView() {
155 default_ = NULL;
158 void TrayDisplay::OnDisplayBoundsChanged(const gfx::Display& display) {
159 if (default_)
160 default_->Update();
163 void TrayDisplay::OnDisplayAdded(const gfx::Display& new_display) {
164 if (default_)
165 default_->Update();
168 void TrayDisplay::OnDisplayRemoved(const gfx::Display& old_display) {
169 if (default_)
170 default_->Update();
173 #if defined(OS_CHROMEOS)
174 void TrayDisplay::OnDisplayModeChanged() {
175 if (default_)
176 default_->Update();
178 #endif
180 } // namespace internal
181 } // namespace ash