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

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

Powered by Google App Engine
This is Rietveld 408576698