Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Side by Side Diff: ash/system/chromeos/tray_display.cc

Issue 17445002: Updates the display message in the uber tray. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix test failures Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/system/chromeos/tray_display.h" 5 #include "ash/system/chromeos/tray_display.h"
6 6
7 #include "ash/display/display_controller.h" 7 #include "ash/display/display_controller.h"
8 #include "ash/display/display_manager.h" 8 #include "ash/display/display_manager.h"
9 #include "ash/shell.h" 9 #include "ash/shell.h"
10 #include "ash/system/tray/fixed_sized_image_view.h" 10 #include "ash/system/tray/fixed_sized_image_view.h"
11 #include "ash/system/tray/system_tray.h" 11 #include "ash/system/tray/system_tray.h"
12 #include "ash/system/tray/system_tray_delegate.h" 12 #include "ash/system/tray/system_tray_delegate.h"
13 #include "ash/system/tray/tray_constants.h" 13 #include "ash/system/tray/tray_constants.h"
14 #include "ash/system/tray/tray_notification_view.h" 14 #include "ash/system/tray/tray_notification_view.h"
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "grit/ash_resources.h" 16 #include "grit/ash_resources.h"
17 #include "grit/ash_strings.h" 17 #include "grit/ash_strings.h"
18 #include "ui/base/l10n/l10n_util.h" 18 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/base/resource/resource_bundle.h" 19 #include "ui/base/resource/resource_bundle.h"
20 #include "ui/views/controls/label.h" 20 #include "ui/views/controls/label.h"
21 #include "ui/views/layout/box_layout.h" 21 #include "ui/views/layout/box_layout.h"
22 22
23 namespace ash { 23 namespace ash {
24 namespace internal { 24 namespace internal {
25 namespace { 25 namespace {
26 26
27 TrayDisplayMode GetCurrentTrayDisplayMode() { 27 DisplayManager* GetDisplayManager() {
28 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 28 return Shell::GetInstance()->display_manager();
29 if (display_manager->GetNumDisplays() > 1) 29 }
30 return TRAY_DISPLAY_EXTENDED;
31 30
32 if (display_manager->IsMirrored()) 31 base::string16 GetDisplayName(int64 display_id) {
33 return TRAY_DISPLAY_MIRRORED; 32 return UTF8ToUTF16(GetDisplayManager()->GetDisplayNameForId(display_id));
33 }
34 34
35 int64 first_id = display_manager->first_display_id(); 35 base::string16 GetDisplaySize(int64 display_id) {
36 if (display_manager->HasInternalDisplay() && 36 return UTF8ToUTF16(
37 !display_manager->IsInternalDisplayId(first_id)) { 37 GetDisplayManager()->GetDisplayForId(display_id).size().ToString());
38 return TRAY_DISPLAY_DOCKED; 38 }
39 }
40 39
41 return TRAY_DISPLAY_SINGLE; 40 bool ShouldShowResolution(int64 display_id) {
41 if (!GetDisplayManager()->GetDisplayForId(display_id).is_valid())
42 return false;
43
44 const DisplayInfo& display_info =
45 GetDisplayManager()->GetDisplayInfo(display_id);
46 return display_info.rotation() != gfx::Display::ROTATE_0 ||
47 display_info.ui_scale() != 1.0f;
42 } 48 }
43 49
44 // Returns the name of the currently connected external display. 50 // Returns the name of the currently connected external display.
45 base::string16 GetExternalDisplayName() { 51 base::string16 GetExternalDisplayName() {
46 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 52 DisplayManager* display_manager = GetDisplayManager();
47 int64 external_id = display_manager->mirrored_display().id(); 53 int64 external_id = display_manager->mirrored_display().id();
48 54
49 if (external_id == gfx::Display::kInvalidDisplayID) { 55 if (external_id == gfx::Display::kInvalidDisplayID) {
50 int64 internal_display_id = gfx::Display::InternalDisplayId(); 56 int64 internal_display_id = gfx::Display::InternalDisplayId();
51 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { 57 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
52 int64 id = display_manager->GetDisplayAt(i)->id(); 58 int64 id = display_manager->GetDisplayAt(i)->id();
53 if (id != internal_display_id) { 59 if (id != internal_display_id) {
54 external_id = id; 60 external_id = id;
55 break; 61 break;
56 } 62 }
57 } 63 }
58 } 64 }
59 if (external_id != gfx::Display::kInvalidDisplayID) 65
60 return UTF8ToUTF16(display_manager->GetDisplayNameForId(external_id)); 66 if (external_id == gfx::Display::kInvalidDisplayID)
61 return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); 67 return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME);
68
69 // The external display name may have an annotation of "(width x height)" in
70 // case that the display is rotated or its resolution is changed.
71 base::string16 name = GetDisplayName(external_id);
72 if (ShouldShowResolution(external_id))
73 name += UTF8ToUTF16(" (") + GetDisplaySize(external_id) + UTF8ToUTF16(")");
74
75 return name;
62 } 76 }
63 77
64 class DisplayViewBase { 78 base::string16 GetTrayDisplayMessage() {
65 public: 79 DisplayManager* display_manager = GetDisplayManager();
66 DisplayViewBase(user::LoginStatus login_status) 80 if (display_manager->GetNumDisplays() > 1) {
67 : login_status_(login_status) { 81 if (GetDisplayManager()->HasInternalDisplay()) {
68 label_ = new views::Label(); 82 return l10n_util::GetStringFUTF16(
69 label_->SetMultiLine(true); 83 IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, GetExternalDisplayName());
70 label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 84 }
85 return l10n_util::GetStringUTF16(
86 IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL);
71 } 87 }
72 88
73 virtual ~DisplayViewBase() { 89 if (display_manager->IsMirrored()) {
90 if (GetDisplayManager()->HasInternalDisplay()) {
91 return l10n_util::GetStringFUTF16(
92 IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetExternalDisplayName());
93 }
94 return l10n_util::GetStringUTF16(
95 IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING_NO_INTERNAL);
74 } 96 }
75 97
76 protected: 98 int64 first_id = display_manager->first_display_id();
77 void OpenSettings() { 99 if (display_manager->HasInternalDisplay() &&
78 if (login_status_ == ash::user::LOGGED_IN_USER || 100 !display_manager->IsInternalDisplayId(first_id)) {
79 login_status_ == ash::user::LOGGED_IN_OWNER || 101 return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED);
80 login_status_ == ash::user::LOGGED_IN_GUEST) {
81 ash::Shell::GetInstance()->system_tray_delegate()->ShowDisplaySettings();
82 }
83 } 102 }
84 103
85 bool UpdateLabelText() { 104 return base::string16();
86 switch (GetCurrentTrayDisplayMode()) { 105 }
87 case TRAY_DISPLAY_SINGLE: 106
88 // TODO(oshima|mukai): Support single display mode for overscan 107 void OpenSettings(user::LoginStatus login_status) {
89 // alignment. 108 if (login_status == ash::user::LOGGED_IN_USER ||
90 return false; 109 login_status == ash::user::LOGGED_IN_OWNER ||
91 case TRAY_DISPLAY_EXTENDED: 110 login_status == ash::user::LOGGED_IN_GUEST) {
92 if (Shell::GetInstance()->display_manager()->HasInternalDisplay()) { 111 ash::Shell::GetInstance()->system_tray_delegate()->ShowDisplaySettings();
93 label_->SetText(l10n_util::GetStringFUTF16(
94 IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, GetExternalDisplayName()));
95 } else {
96 label_->SetText(l10n_util::GetStringUTF16(
97 IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL));
98 }
99 break;
100 case TRAY_DISPLAY_MIRRORED:
101 if (Shell::GetInstance()->display_manager()->HasInternalDisplay()) {
102 label_->SetText(l10n_util::GetStringFUTF16(
103 IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetExternalDisplayName()));
104 } else {
105 label_->SetText(l10n_util::GetStringUTF16(
106 IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING_NO_INTERNAL));
107 }
108 break;
109 case TRAY_DISPLAY_DOCKED:
110 label_->SetText(l10n_util::GetStringUTF16(
111 IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED));
112 break;
113 }
114 return true;
115 } 112 }
116 113 }
117 views::Label* label() { return label_; }
118
119 private:
120 user::LoginStatus login_status_;
121 views::Label* label_;
122
123 DISALLOW_COPY_AND_ASSIGN(DisplayViewBase);
124 };
125 114
126 } // namespace 115 } // namespace
127 116
128 class DisplayView : public DisplayViewBase, 117 class DisplayView : public ash::internal::ActionableView {
129 public ash::internal::ActionableView {
130 public: 118 public:
131 explicit DisplayView(user::LoginStatus login_status) 119 explicit DisplayView(user::LoginStatus login_status)
132 : DisplayViewBase(login_status) { 120 : login_status_(login_status) {
133 SetLayoutManager(new 121 SetLayoutManager(new
134 views::BoxLayout(views::BoxLayout::kHorizontal, 122 views::BoxLayout(views::BoxLayout::kHorizontal,
135 ash::kTrayPopupPaddingHorizontal, 0, 123 ash::kTrayPopupPaddingHorizontal, 0,
136 ash::kTrayPopupPaddingBetweenItems)); 124 ash::kTrayPopupPaddingBetweenItems));
137 125
138 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); 126 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
139 image_ = 127 image_ =
140 new ash::internal::FixedSizedImageView(0, ash::kTrayPopupItemHeight); 128 new ash::internal::FixedSizedImageView(0, ash::kTrayPopupItemHeight);
141 image_->SetImage( 129 image_->SetImage(
142 bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY).ToImageSkia()); 130 bundle.GetImageNamed(IDR_AURA_UBER_TRAY_DISPLAY).ToImageSkia());
143 AddChildView(image_); 131 AddChildView(image_);
144 AddChildView(label()); 132
133 label_ = new views::Label();
134 label_->SetMultiLine(true);
135 label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
136 AddChildView(label_);
145 Update(); 137 Update();
146 } 138 }
147 139
148 virtual ~DisplayView() {} 140 virtual ~DisplayView() {}
149 141
150 void Update() { 142 void Update() {
151 SetVisible(UpdateLabelText()); 143 base::string16 message = GetTrayDisplayMessage();
144 if (message.empty())
145 message = GetInternalDisplayInfo();
146 SetVisible(!message.empty());
147 label_->SetText(message);
152 } 148 }
153 149
150 views::Label* label() { return label_; }
151
154 private: 152 private:
153 base::string16 GetInternalDisplayInfo() const {
154 int64 first_id = GetDisplayManager()->first_display_id();
155 if (!ShouldShowResolution(first_id))
156 return base::string16();
157
158 return l10n_util::GetStringFUTF16(
159 IDS_ASH_STATUS_TRAY_DISPLAY_SINGLE_DISPLAY,
160 GetDisplayName(first_id),
161 GetDisplaySize(first_id));
162 }
163
155 // Overridden from ActionableView. 164 // Overridden from ActionableView.
156 virtual bool PerformAction(const ui::Event& event) OVERRIDE { 165 virtual bool PerformAction(const ui::Event& event) OVERRIDE {
157 OpenSettings(); 166 OpenSettings(login_status_);
158 return true; 167 return true;
159 } 168 }
160 169
161 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE { 170 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE {
162 int label_max_width = bounds().width() - kTrayPopupPaddingHorizontal * 2 - 171 int label_max_width = bounds().width() - kTrayPopupPaddingHorizontal * 2 -
163 kTrayPopupPaddingBetweenItems - image_->GetPreferredSize().width(); 172 kTrayPopupPaddingBetweenItems - image_->GetPreferredSize().width();
164 label()->SizeToFit(label_max_width); 173 label_->SizeToFit(label_max_width);
165 PreferredSizeChanged(); 174 PreferredSizeChanged();
166 } 175 }
167 176
177 // Overridden from views::View.
178 virtual bool GetTooltipText(const gfx::Point& p,
179 string16* tooltip) const OVERRIDE {
180 base::string16 tray_message = GetTrayDisplayMessage();
181 base::string16 internal_message = GetInternalDisplayInfo();
182 if (tray_message.empty() && internal_message.empty())
183 return false;
184
185 *tooltip = tray_message + base::string16(1, '\n') + internal_message;
186 return true;
187 }
188
189 user::LoginStatus login_status_;
168 views::ImageView* image_; 190 views::ImageView* image_;
191 views::Label* label_;
169 192
170 DISALLOW_COPY_AND_ASSIGN(DisplayView); 193 DISALLOW_COPY_AND_ASSIGN(DisplayView);
171 }; 194 };
172 195
173 class DisplayNotificationView : public DisplayViewBase, 196 class DisplayNotificationView : public TrayNotificationView {
174 public TrayNotificationView {
175 public: 197 public:
176 DisplayNotificationView(user::LoginStatus login_status, 198 DisplayNotificationView(user::LoginStatus login_status,
177 TrayDisplay* tray_item) 199 TrayDisplay* tray_item,
178 : DisplayViewBase(login_status), 200 const base::string16& message)
179 TrayNotificationView(tray_item, IDR_AURA_UBER_TRAY_DISPLAY) { 201 : TrayNotificationView(tray_item, IDR_AURA_UBER_TRAY_DISPLAY),
180 InitView(label()); 202 login_status_(login_status) {
181 StartAutoCloseTimer(kTrayPopupAutoCloseDelayForTextInSeconds); 203 StartAutoCloseTimer(kTrayPopupAutoCloseDelayForTextInSeconds);
182 Update(); 204 Update(message);
183 } 205 }
184 206
185 virtual ~DisplayNotificationView() {} 207 virtual ~DisplayNotificationView() {}
186 208
187 void Update() { 209 void Update(const base::string16& message) {
188 if (UpdateLabelText()) 210 if (message.empty()) {
211 owner()->HideNotificationView();
212 } else {
213 views::Label* label = new views::Label(message);
214 label->SetMultiLine(true);
215 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
216 UpdateView(label);
189 RestartAutoCloseTimer(); 217 RestartAutoCloseTimer();
190 else 218 }
191 owner()->HideNotificationView();
192 } 219 }
193 220
194 // Overridden from TrayNotificationView: 221 // Overridden from TrayNotificationView:
195 virtual void OnClickAction() OVERRIDE { 222 virtual void OnClickAction() OVERRIDE {
196 OpenSettings(); 223 OpenSettings(login_status_);
197 } 224 }
198 225
199 private: 226 private:
227 user::LoginStatus login_status_;
228
200 DISALLOW_COPY_AND_ASSIGN(DisplayNotificationView); 229 DISALLOW_COPY_AND_ASSIGN(DisplayNotificationView);
201 }; 230 };
202 231
203 TrayDisplay::TrayDisplay(SystemTray* system_tray) 232 TrayDisplay::TrayDisplay(SystemTray* system_tray)
204 : SystemTrayItem(system_tray), 233 : SystemTrayItem(system_tray),
205 default_(NULL), 234 default_(NULL),
206 notification_(NULL), 235 notification_(NULL) {
207 current_mode_(GetCurrentTrayDisplayMode()) { 236 current_message_ = GetDisplayMessageForNotification();
208 Shell::GetInstance()->display_controller()->AddObserver(this); 237 Shell::GetInstance()->display_controller()->AddObserver(this);
209 } 238 }
210 239
211 TrayDisplay::~TrayDisplay() { 240 TrayDisplay::~TrayDisplay() {
212 Shell::GetInstance()->display_controller()->RemoveObserver(this); 241 Shell::GetInstance()->display_controller()->RemoveObserver(this);
213 } 242 }
214 243
244 base::string16 TrayDisplay::GetDisplayMessageForNotification() {
245 DisplayManager* display_manager = GetDisplayManager();
246 std::map<int64, DisplayInfo> old_info;
247 old_info.swap(display_info_);
248 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
249 int64 id = display_manager->GetDisplayAt(i)->id();
250 display_info_[id] = display_manager->GetDisplayInfo(id);
251 }
252
253 if (display_info_.size() == old_info.size()) {
254 for (std::map<int64, DisplayInfo>::const_iterator iter =
255 display_info_.begin(); iter != display_info_.end(); ++iter) {
256 std::map<int64, DisplayInfo>::const_iterator old_iter =
257 old_info.find(iter->first);
258 if (old_iter == old_info.end())
259 break;
260
261 if (iter->second.ui_scale() != old_iter->second.ui_scale()) {
262 return l10n_util::GetStringFUTF16(
263 IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED,
264 GetDisplayName(iter->first),
265 GetDisplaySize(iter->first));
266 }
267 if (iter->second.rotation() != old_iter->second.rotation()) {
268 return l10n_util::GetStringFUTF16(
269 IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED, GetDisplayName(iter->first));
270 }
271 }
272 }
273
274 return GetTrayDisplayMessage();
275 }
276
215 views::View* TrayDisplay::CreateDefaultView(user::LoginStatus status) { 277 views::View* TrayDisplay::CreateDefaultView(user::LoginStatus status) {
216 DCHECK(default_ == NULL); 278 DCHECK(default_ == NULL);
217 default_ = new DisplayView(status); 279 default_ = new DisplayView(status);
218 return default_; 280 return default_;
219 } 281 }
220 282
221 views::View* TrayDisplay::CreateNotificationView(user::LoginStatus status) { 283 views::View* TrayDisplay::CreateNotificationView(user::LoginStatus status) {
222 DCHECK(notification_ == NULL); 284 DCHECK(notification_ == NULL);
223 notification_ = new DisplayNotificationView(status, this); 285 notification_ = new DisplayNotificationView(status, this, current_message_);
224 return notification_; 286 return notification_;
225 } 287 }
226 288
227 void TrayDisplay::DestroyDefaultView() { 289 void TrayDisplay::DestroyDefaultView() {
228 default_ = NULL; 290 default_ = NULL;
229 } 291 }
230 292
231 void TrayDisplay::DestroyNotificationView() { 293 void TrayDisplay::DestroyNotificationView() {
232 notification_ = NULL; 294 notification_ = NULL;
233 } 295 }
234 296
235 bool TrayDisplay::ShouldShowLauncher() const { 297 bool TrayDisplay::ShouldShowLauncher() const {
236 return false; 298 return false;
237 } 299 }
238 300
239 void TrayDisplay::OnDisplayConfigurationChanged() { 301 void TrayDisplay::OnDisplayConfigurationChanged() {
240 TrayDisplayMode new_mode = GetCurrentTrayDisplayMode(); 302 // TODO(mukai): do not show the notification when the configuration changed
241 if (current_mode_ != new_mode && new_mode != TRAY_DISPLAY_SINGLE) { 303 // due to the user operation on display settings page.
242 if (notification_) 304 current_message_ = GetDisplayMessageForNotification();
243 notification_->Update(); 305 if (notification_)
244 else 306 notification_->Update(current_message_);
245 ShowNotificationView(); 307 else if (!current_message_.empty())
246 } 308 ShowNotificationView();
247 current_mode_ = new_mode; 309 }
310
311 bool TrayDisplay::IsDisplayViewVisibleForTest() {
312 return default_ && default_->visible();
313 }
314
315 base::string16 TrayDisplay::GetTrayDisplayTextForTest() {
316 if (!default_)
317 return base::string16();
318 return default_->label()->text();
319 }
320
321 base::string16 TrayDisplay::GetTrayDisplayTooltipTextForTest() {
322 base::string16 tooltip;
323 if (!default_)
324 return base::string16();
325
326 static_cast<views::View*>(default_)->GetTooltipText(gfx::Point(), &tooltip);
oshima 2013/06/20 21:28:57 isn't DefaultView a view? also it's probably bette
Jun Mukai 2013/06/20 22:03:07 done
327 return tooltip;
328 }
329
330 base::string16 TrayDisplay::GetDisplayNotificationTextForTest() {
331 return current_message_;
248 } 332 }
249 333
250 } // namespace internal 334 } // namespace internal
251 } // namespace ash 335 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698