tray_display.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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.
4
5#include "ash/system/chromeos/tray_display.h"
6
7#include "ash/display/display_controller.h"
8#include "ash/display/multi_display_manager.h"
9#include "ash/screen_ash.h"
10#include "ash/shell.h"
11#include "ash/system/tray/system_tray.h"
12#include "ash/system/tray/system_tray_delegate.h"
13#include "ash/system/tray/tray_constants.h"
14#include "ash/system/tray/tray_views.h"
15#include "base/utf_string_conversions.h"
16#include "grit/ash_resources.h"
17#include "grit/ash_strings.h"
18#include "ui/aura/display_manager.h"
19#include "ui/aura/env.h"
20#include "ui/base/l10n/l10n_util.h"
21#include "ui/base/resource/resource_bundle.h"
22#include "ui/gfx/image/image.h"
23#include "ui/views/controls/image_view.h"
24#include "ui/views/controls/label.h"
25#include "ui/views/layout/box_layout.h"
26
27namespace ash {
28namespace internal {
29
30class DisplayView : public ash::internal::ActionableView {
31 public:
32  explicit DisplayView(user::LoginStatus login_status)
33      : login_status_(login_status) {
34    SetLayoutManager(new
35        views::BoxLayout(views::BoxLayout::kHorizontal,
36        ash::kTrayPopupPaddingHorizontal, 0,
37        ash::kTrayPopupPaddingBetweenItems));
38
39    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
40    views::ImageView* image =
41        new ash::internal::FixedSizedImageView(0, ash::kTrayPopupItemHeight);
42    image->SetImage(
43        bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY).ToImageSkia());
44    AddChildView(image);
45    label_ = new views::Label();
46    AddChildView(label_);
47    Update();
48  }
49
50  virtual ~DisplayView() {}
51
52  void Update() {
53    switch (Shell::GetInstance()->output_configurator()->output_state()) {
54      case chromeos::STATE_INVALID:
55      case chromeos::STATE_HEADLESS:
56      case chromeos::STATE_SINGLE:
57        SetVisible(false);
58        return;
59      case chromeos::STATE_DUAL_MIRROR: {
60        label_->SetText(l10n_util::GetStringFUTF16(
61            IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetExternalDisplayName()));
62        SetVisible(true);
63        return;
64      }
65      case chromeos::STATE_DUAL_PRIMARY_ONLY:
66      case chromeos::STATE_DUAL_SECONDARY_ONLY:
67      case chromeos::STATE_DUAL_UNKNOWN: {
68        label_->SetText(l10n_util::GetStringFUTF16(
69            IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, GetExternalDisplayName()));
70        SetVisible(true);
71        return;
72      }
73      default:
74        NOTREACHED();
75    }
76  }
77
78 private:
79  // Returns the name of the currently connected external display.
80  string16 GetExternalDisplayName() {
81    MultiDisplayManager* display_manager = static_cast<MultiDisplayManager*>(
82        aura::Env::GetInstance()->display_manager());
83
84    gfx::Display external_display(gfx::Display::kInvalidDisplayID);
85    if (display_manager->HasInternalDisplay()) {
86      for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
87        gfx::Display* display = display_manager->GetDisplayAt(i);
88        if (!display_manager->IsInternalDisplayId(display->id())) {
89          external_display = *display;
90          break;
91        }
92      }
93    } else {
94      // Falls back to the secondary display since the system doesn't
95      // distinguish the displays.
96      external_display = ScreenAsh::GetSecondaryDisplay();
97    }
98
99    return UTF8ToUTF16(display_manager->GetDisplayNameFor(external_display));
100  }
101
102  // Overridden from ActionableView.
103  virtual bool PerformAction(const ui::Event& event) OVERRIDE {
104    if (login_status_ == ash::user::LOGGED_IN_USER ||
105        login_status_ == ash::user::LOGGED_IN_OWNER ||
106        login_status_ == ash::user::LOGGED_IN_GUEST) {
107      ash::Shell::GetInstance()->tray_delegate()->ShowDisplaySettings();
108    }
109
110    return true;
111  }
112
113  user::LoginStatus login_status_;
114  views::Label* label_;
115
116  DISALLOW_COPY_AND_ASSIGN(DisplayView);
117};
118
119TrayDisplay::TrayDisplay()
120    : default_(NULL) {
121  aura::Env::GetInstance()->display_manager()->AddObserver(this);
122  ash::Shell::GetInstance()->output_configurator()->AddObserver(this);
123}
124
125TrayDisplay::~TrayDisplay() {
126  aura::Env::GetInstance()->display_manager()->RemoveObserver(this);
127  ash::Shell::GetInstance()->output_configurator()->RemoveObserver(this);
128}
129
130views::View* TrayDisplay::CreateDefaultView(user::LoginStatus status) {
131  default_ = new DisplayView(status);
132  return default_;
133}
134
135void TrayDisplay::DestroyDefaultView() {
136  default_ = NULL;
137}
138
139void TrayDisplay::OnDisplayBoundsChanged(const gfx::Display& display) {
140  if (default_)
141    default_->Update();
142}
143
144void TrayDisplay::OnDisplayAdded(const gfx::Display& new_display) {
145  if (default_)
146    default_->Update();
147}
148
149void TrayDisplay::OnDisplayRemoved(const gfx::Display& old_display) {
150  if (default_)
151    default_->Update();
152}
153
154void TrayDisplay::OnDisplayModeChanged() {
155  if (default_)
156    default_->Update();
157}
158
159}  // namespace internal
160}  // namespace ash
161