OLD | NEW |
---|---|
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/user/tray_user.h" | 5 #include "ash/system/user/tray_user.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <climits> | 8 #include <climits> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "ash/ash_switches.h" | 11 #include "ash/ash_switches.h" |
12 #include "ash/metrics/user_metrics_recorder.h" | 12 #include "ash/metrics/user_metrics_recorder.h" |
13 #include "ash/multi_profile_uma.h" | 13 #include "ash/multi_profile_uma.h" |
14 #include "ash/popup_message.h" | 14 #include "ash/popup_message.h" |
15 #include "ash/root_window_controller.h" | 15 #include "ash/root_window_controller.h" |
16 #include "ash/session_state_delegate.h" | 16 #include "ash/session_state_delegate.h" |
17 #include "ash/shelf/shelf_layout_manager.h" | 17 #include "ash/shelf/shelf_layout_manager.h" |
18 #include "ash/shell.h" | 18 #include "ash/shell.h" |
19 #include "ash/shell_delegate.h" | 19 #include "ash/shell_delegate.h" |
20 #include "ash/system/tray/fixed_sized_scroll_view.h" | |
21 #include "ash/system/tray/hover_highlight_view.h" | |
20 #include "ash/system/tray/system_tray.h" | 22 #include "ash/system/tray/system_tray.h" |
21 #include "ash/system/tray/system_tray_delegate.h" | 23 #include "ash/system/tray/system_tray_delegate.h" |
22 #include "ash/system/tray/system_tray_notifier.h" | 24 #include "ash/system/tray/system_tray_notifier.h" |
23 #include "ash/system/tray/tray_constants.h" | 25 #include "ash/system/tray/tray_constants.h" |
26 #include "ash/system/tray/tray_details_view.h" | |
24 #include "ash/system/tray/tray_item_view.h" | 27 #include "ash/system/tray/tray_item_view.h" |
28 #include "ash/system/tray/tray_popup_header_button.h" | |
25 #include "ash/system/tray/tray_popup_label_button.h" | 29 #include "ash/system/tray/tray_popup_label_button.h" |
26 #include "ash/system/tray/tray_popup_label_button_border.h" | 30 #include "ash/system/tray/tray_popup_label_button_border.h" |
27 #include "ash/system/tray/tray_utils.h" | 31 #include "ash/system/tray/tray_utils.h" |
32 #include "ash/system/tray/view_click_listener.h" | |
33 #include "ash/system/user/user_accounts_delegate.h" | |
28 #include "base/i18n/rtl.h" | 34 #include "base/i18n/rtl.h" |
29 #include "base/logging.h" | 35 #include "base/logging.h" |
30 #include "base/memory/scoped_vector.h" | 36 #include "base/memory/scoped_vector.h" |
31 #include "base/strings/string16.h" | 37 #include "base/strings/string16.h" |
32 #include "base/strings/string_util.h" | 38 #include "base/strings/string_util.h" |
33 #include "base/strings/utf_string_conversions.h" | 39 #include "base/strings/utf_string_conversions.h" |
34 #include "grit/ash_resources.h" | 40 #include "grit/ash_resources.h" |
35 #include "grit/ash_strings.h" | 41 #include "grit/ash_strings.h" |
42 #include "grit/ui_resources.h" | |
36 #include "skia/ext/image_operations.h" | 43 #include "skia/ext/image_operations.h" |
37 #include "third_party/skia/include/core/SkCanvas.h" | 44 #include "third_party/skia/include/core/SkCanvas.h" |
38 #include "third_party/skia/include/core/SkPaint.h" | 45 #include "third_party/skia/include/core/SkPaint.h" |
39 #include "third_party/skia/include/core/SkPath.h" | 46 #include "third_party/skia/include/core/SkPath.h" |
40 #include "ui/aura/window.h" | 47 #include "ui/aura/window.h" |
41 #include "ui/base/l10n/l10n_util.h" | 48 #include "ui/base/l10n/l10n_util.h" |
42 #include "ui/base/resource/resource_bundle.h" | 49 #include "ui/base/resource/resource_bundle.h" |
43 #include "ui/gfx/canvas.h" | 50 #include "ui/gfx/canvas.h" |
44 #include "ui/gfx/font_list.h" | 51 #include "ui/gfx/font_list.h" |
45 #include "ui/gfx/image/image.h" | 52 #include "ui/gfx/image/image.h" |
46 #include "ui/gfx/image/image_skia_operations.h" | 53 #include "ui/gfx/image/image_skia_operations.h" |
47 #include "ui/gfx/insets.h" | 54 #include "ui/gfx/insets.h" |
48 #include "ui/gfx/range/range.h" | 55 #include "ui/gfx/range/range.h" |
49 #include "ui/gfx/rect.h" | 56 #include "ui/gfx/rect.h" |
50 #include "ui/gfx/render_text.h" | 57 #include "ui/gfx/render_text.h" |
51 #include "ui/gfx/size.h" | 58 #include "ui/gfx/size.h" |
52 #include "ui/gfx/skia_util.h" | 59 #include "ui/gfx/skia_util.h" |
53 #include "ui/gfx/text_elider.h" | 60 #include "ui/gfx/text_elider.h" |
54 #include "ui/gfx/text_utils.h" | 61 #include "ui/gfx/text_utils.h" |
55 #include "ui/views/border.h" | 62 #include "ui/views/border.h" |
56 #include "ui/views/bubble/tray_bubble_view.h" | 63 #include "ui/views/bubble/tray_bubble_view.h" |
57 #include "ui/views/controls/button/button.h" | 64 #include "ui/views/controls/button/button.h" |
58 #include "ui/views/controls/button/custom_button.h" | 65 #include "ui/views/controls/button/custom_button.h" |
66 #include "ui/views/controls/button/image_button.h" | |
59 #include "ui/views/controls/image_view.h" | 67 #include "ui/views/controls/image_view.h" |
60 #include "ui/views/controls/label.h" | 68 #include "ui/views/controls/label.h" |
61 #include "ui/views/controls/link.h" | 69 #include "ui/views/controls/link.h" |
62 #include "ui/views/controls/link_listener.h" | 70 #include "ui/views/controls/link_listener.h" |
63 #include "ui/views/layout/box_layout.h" | 71 #include "ui/views/layout/box_layout.h" |
64 #include "ui/views/layout/fill_layout.h" | 72 #include "ui/views/layout/fill_layout.h" |
73 #include "ui/views/layout/grid_layout.h" | |
65 #include "ui/views/mouse_watcher.h" | 74 #include "ui/views/mouse_watcher.h" |
66 #include "ui/views/painter.h" | 75 #include "ui/views/painter.h" |
67 #include "ui/views/view.h" | 76 #include "ui/views/view.h" |
68 #include "ui/views/widget/widget.h" | 77 #include "ui/views/widget/widget.h" |
69 #include "ui/wm/core/shadow_types.h" | 78 #include "ui/wm/core/shadow_types.h" |
70 | 79 |
71 namespace { | 80 namespace { |
72 | 81 |
73 const int kUserDetailsVerticalPadding = 5; | 82 const int kUserDetailsVerticalPadding = 5; |
74 const int kUserCardVerticalPadding = 10; | 83 const int kUserCardVerticalPadding = 10; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 delegate->SwitchActiveUser(delegate->GetUserID(user_index)); | 140 delegate->SwitchActiveUser(delegate->GetUserID(user_index)); |
132 } | 141 } |
133 | 142 |
134 } // namespace | 143 } // namespace |
135 | 144 |
136 namespace ash { | 145 namespace ash { |
137 namespace internal { | 146 namespace internal { |
138 | 147 |
139 namespace tray { | 148 namespace tray { |
140 | 149 |
150 // Returns true when multi profile is supported. | |
151 bool IsMultiProfileSupported() { | |
152 // We do not want to see any multi profile additions to a user view when the | |
153 // log in screen is shown. | |
154 return Shell::GetInstance()->delegate()->IsMultiProfilesEnabled() && | |
155 !Shell::GetInstance() | |
156 ->session_state_delegate() | |
157 ->IsUserSessionBlocked(); | |
158 } | |
159 | |
160 // Returns true if account management is supported. | |
161 bool IsAccountManagementSupported() { | |
162 return Shell::GetInstance()->delegate()->IsAccountManagementEnabled(); | |
163 } | |
164 | |
141 // A custom image view with rounded edges. | 165 // A custom image view with rounded edges. |
142 class RoundedImageView : public views::View { | 166 class RoundedImageView : public views::View { |
143 public: | 167 public: |
144 // Constructs a new rounded image view with rounded corners of radius | 168 // Constructs a new rounded image view with rounded corners of radius |
145 // |corner_radius|. If |active_user| is set, the icon will be drawn in | 169 // |corner_radius|. If |active_user| is set, the icon will be drawn in |
146 // full colors - otherwise it will fade into the background. | 170 // full colors - otherwise it will fade into the background. |
147 RoundedImageView(int corner_radius, bool active_user); | 171 RoundedImageView(int corner_radius, bool active_user); |
148 virtual ~RoundedImageView(); | 172 virtual ~RoundedImageView(); |
149 | 173 |
150 // Set the image that should be displayed. The image contents is copied to the | 174 // Set the image that should be displayed. The image contents is copied to the |
(...skipping 22 matching lines...) Expand all Loading... | |
173 | 197 |
174 DISALLOW_COPY_AND_ASSIGN(RoundedImageView); | 198 DISALLOW_COPY_AND_ASSIGN(RoundedImageView); |
175 }; | 199 }; |
176 | 200 |
177 // The user details shown in public account mode. This is essentially a label | 201 // The user details shown in public account mode. This is essentially a label |
178 // but with custom painting code as the text is styled with multiple colors and | 202 // but with custom painting code as the text is styled with multiple colors and |
179 // contains a link. | 203 // contains a link. |
180 class PublicAccountUserDetails : public views::View, | 204 class PublicAccountUserDetails : public views::View, |
181 public views::LinkListener { | 205 public views::LinkListener { |
182 public: | 206 public: |
183 PublicAccountUserDetails(SystemTrayItem* owner, int used_width); | 207 PublicAccountUserDetails(int max_width); |
184 virtual ~PublicAccountUserDetails(); | 208 virtual ~PublicAccountUserDetails(); |
185 | 209 |
186 private: | 210 private: |
187 // Overridden from views::View. | 211 // Overridden from views::View. |
188 virtual void Layout() OVERRIDE; | 212 virtual void Layout() OVERRIDE; |
189 virtual gfx::Size GetPreferredSize() OVERRIDE; | 213 virtual gfx::Size GetPreferredSize() OVERRIDE; |
190 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; | 214 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; |
191 | 215 |
192 // Overridden from views::LinkListener. | 216 // Overridden from views::LinkListener. |
193 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; | 217 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; |
194 | 218 |
195 // Calculate a preferred size that ensures the label text and the following | 219 // Calculate a preferred size that ensures the label text and the following |
196 // link do not wrap over more than three lines in total for aesthetic reasons | 220 // link do not wrap over more than three lines in total for aesthetic reasons |
197 // if possible. | 221 // if possible. |
198 void CalculatePreferredSize(SystemTrayItem* owner, int used_width); | 222 void CalculatePreferredSize(int max_allowed_width); |
199 | 223 |
200 base::string16 text_; | 224 base::string16 text_; |
201 views::Link* learn_more_; | 225 views::Link* learn_more_; |
202 gfx::Size preferred_size_; | 226 gfx::Size preferred_size_; |
203 ScopedVector<gfx::RenderText> lines_; | 227 ScopedVector<gfx::RenderText> lines_; |
204 | 228 |
205 DISALLOW_COPY_AND_ASSIGN(PublicAccountUserDetails); | 229 DISALLOW_COPY_AND_ASSIGN(PublicAccountUserDetails); |
206 }; | 230 }; |
207 | 231 |
208 // The button which holds the user card in case of multi profile. | 232 // This view is used to wrap it's content and transform it into button. |
209 class UserCard : public views::CustomButton { | 233 class WrappingButtonView : public views::CustomButton { |
210 public: | 234 public: |
211 UserCard(views::ButtonListener* listener, bool active_user); | 235 WrappingButtonView(views::View* content, |
212 virtual ~UserCard(); | 236 views::ButtonListener* listener, |
237 bool highlight_on_hover); | |
238 virtual ~WrappingButtonView(); | |
213 | 239 |
214 // Called when the border should remain even in the non highlighted state. | 240 // Called when the border should remain even in the non highlighted state. |
215 void ForceBorderVisible(bool show); | 241 void ForceBorderVisible(bool show); |
216 | 242 |
217 // Overridden from views::View | 243 // Overridden from views::View |
218 virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; | 244 virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; |
219 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; | 245 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; |
220 | 246 |
221 // Check if the item is hovered. | 247 // Check if the item is hovered. |
222 bool is_hovered_for_test() {return button_hovered_; } | 248 bool is_hovered_for_test() {return button_hovered_; } |
223 | 249 |
224 private: | 250 private: |
225 // Change the hover/active state of the "button" when the status changes. | 251 // Change the hover/active state of the "button" when the status changes. |
226 void ShowActive(); | 252 void ShowActive(); |
227 | 253 |
228 // True if this is the active user. | 254 // Content of button. |
229 bool is_active_user_; | 255 views::View* content_; |
256 | |
257 // Whether button should be highligthed on hover. | |
258 bool highlight_on_hover_; | |
230 | 259 |
231 // True if button is hovered. | 260 // True if button is hovered. |
232 bool button_hovered_; | 261 bool button_hovered_; |
233 | 262 |
234 // True if the border should be visible. | 263 // True if the border should be always visible. |
235 bool show_border_; | 264 bool show_border_; |
236 | 265 |
237 DISALLOW_COPY_AND_ASSIGN(UserCard); | 266 DISALLOW_COPY_AND_ASSIGN(WrappingButtonView); |
238 }; | 267 }; |
239 | 268 |
240 class UserViewMouseWatcherHost : public views::MouseWatcherHost { | 269 class UserViewMouseWatcherHost : public views::MouseWatcherHost { |
241 public: | 270 public: |
242 explicit UserViewMouseWatcherHost(const gfx::Rect& screen_area) | 271 explicit UserViewMouseWatcherHost(const gfx::Rect& screen_area) |
243 : screen_area_(screen_area) {} | 272 : screen_area_(screen_area) {} |
244 virtual ~UserViewMouseWatcherHost() {} | 273 virtual ~UserViewMouseWatcherHost() {} |
245 | 274 |
246 // Implementation of MouseWatcherHost. | 275 // Implementation of MouseWatcherHost. |
247 virtual bool Contains(const gfx::Point& screen_point, | 276 virtual bool Contains(const gfx::Point& screen_point, |
248 views::MouseWatcherHost::MouseEventType type) OVERRIDE { | 277 views::MouseWatcherHost::MouseEventType type) OVERRIDE { |
249 return screen_area_.Contains(screen_point); | 278 return screen_area_.Contains(screen_point); |
250 } | 279 } |
251 | 280 |
252 private: | 281 private: |
253 gfx::Rect screen_area_; | 282 gfx::Rect screen_area_; |
254 | 283 |
255 DISALLOW_COPY_AND_ASSIGN(UserViewMouseWatcherHost); | 284 DISALLOW_COPY_AND_ASSIGN(UserViewMouseWatcherHost); |
256 }; | 285 }; |
257 | 286 |
258 // The view of a user item. | 287 // The view of a user item. |
259 class UserView : public views::View, | 288 class UserView : public views::View, |
260 public views::ButtonListener, | 289 public views::ButtonListener, |
261 public views::MouseWatcherListener { | 290 public views::MouseWatcherListener { |
262 public: | 291 public: |
263 UserView(SystemTrayItem* owner, | 292 UserView(SystemTrayItem* owner, |
264 ash::user::LoginStatus login, | 293 ash::user::LoginStatus login, |
265 MultiProfileIndex index); | 294 MultiProfileIndex index, |
295 bool for_detailed_view); | |
266 virtual ~UserView(); | 296 virtual ~UserView(); |
267 | 297 |
268 // Overridden from MouseWatcherListener: | 298 // Overridden from MouseWatcherListener: |
269 virtual void MouseMovedOutOfHost() OVERRIDE; | 299 virtual void MouseMovedOutOfHost() OVERRIDE; |
270 | 300 |
271 TrayUser::TestState GetStateForTest() const; | 301 TrayUser::TestState GetStateForTest() const; |
272 gfx::Rect GetBoundsInScreenOfUserButtonForTest(); | 302 gfx::Rect GetBoundsInScreenOfUserButtonForTest(); |
273 | 303 |
274 private: | 304 private: |
275 // Overridden from views::View. | 305 // Overridden from views::View. |
276 virtual gfx::Size GetPreferredSize() OVERRIDE; | 306 virtual gfx::Size GetPreferredSize() OVERRIDE; |
277 virtual int GetHeightForWidth(int width) OVERRIDE; | 307 virtual int GetHeightForWidth(int width) OVERRIDE; |
278 virtual void Layout() OVERRIDE; | 308 virtual void Layout() OVERRIDE; |
279 | 309 |
280 // Overridden from views::ButtonListener. | 310 // Overridden from views::ButtonListener. |
281 virtual void ButtonPressed(views::Button* sender, | 311 virtual void ButtonPressed(views::Button* sender, |
282 const ui::Event& event) OVERRIDE; | 312 const ui::Event& event) OVERRIDE; |
283 | 313 |
284 void AddLogoutButton(user::LoginStatus login); | 314 void AddLogoutButton(user::LoginStatus login); |
285 void AddUserCard(SystemTrayItem* owner, user::LoginStatus login); | 315 void AddUserCard(user::LoginStatus login); |
286 | |
287 // Create a user icon representation for the user card. | |
288 views::View* CreateIconForUserCard(user::LoginStatus login); | |
289 | |
290 // Create the additional user card content for the retail logged in mode. | |
291 void AddLoggedInRetailModeUserCardContent(); | |
292 | |
293 // Create the additional user card content for the public mode. | |
294 void AddLoggedInPublicModeUserCardContent(SystemTrayItem* owner); | |
295 | 316 |
296 // Create the menu option to add another user. If |disabled| is set the user | 317 // Create the menu option to add another user. If |disabled| is set the user |
297 // cannot actively click on the item. | 318 // cannot actively click on the item. |
298 void ToggleAddUserMenuOption(); | 319 void ToggleAddUserMenuOption(); |
299 | 320 |
300 // Returns true when multi profile is supported. | |
301 bool SupportsMultiProfile(); | |
302 | |
303 MultiProfileIndex multiprofile_index_; | 321 MultiProfileIndex multiprofile_index_; |
304 // The view of the user card. | 322 // The view of the user card. |
305 views::View* user_card_view_; | 323 views::View* user_card_view_; |
306 | 324 |
307 // This is the owner system tray item of this view. | 325 // This is the owner system tray item of this view. |
308 SystemTrayItem* owner_; | 326 SystemTrayItem* owner_; |
309 | 327 |
310 // True if |user_card_view_| is a |UserView| - otherwise it is only a | 328 // True if |user_card_view_| is a |WrappingButtonView| - otherwise it is only |
311 // |views::View|. | 329 // a |UserCardView|. |
312 bool is_user_card_; | 330 bool is_user_card_button_; |
331 | |
313 views::View* logout_button_; | 332 views::View* logout_button_; |
314 scoped_ptr<PopupMessage> popup_message_; | 333 scoped_ptr<PopupMessage> popup_message_; |
315 scoped_ptr<views::Widget> add_menu_option_; | 334 scoped_ptr<views::Widget> add_menu_option_; |
316 | 335 |
317 // True when the add user panel is visible but not activatable. | 336 // True when the add user panel is visible but not activatable. |
318 bool add_user_visible_but_disabled_; | 337 bool add_user_disabled_; |
338 | |
339 // True if this view will be used inside detailed view. | |
340 bool for_detailed_view_; | |
319 | 341 |
320 // The mouse watcher which takes care of out of window hover events. | 342 // The mouse watcher which takes care of out of window hover events. |
321 scoped_ptr<views::MouseWatcher> mouse_watcher_; | 343 scoped_ptr<views::MouseWatcher> mouse_watcher_; |
322 | 344 |
323 DISALLOW_COPY_AND_ASSIGN(UserView); | 345 DISALLOW_COPY_AND_ASSIGN(UserView); |
324 }; | 346 }; |
325 | 347 |
326 // The menu item view which gets shown when the user clicks in multi profile | 348 // The menu item view which gets shown when the user clicks in multi profile |
327 // mode onto the user item. | 349 // mode onto the user item. |
328 class AddUserView : public views::CustomButton, | 350 class AddUserView : public views::View { |
329 public views::ButtonListener { | |
330 public: | 351 public: |
331 // The |owner| is the view for which this view gets created. The |listener| | 352 // The |owner| is the view for which this view gets created. |
332 // will get notified when this item gets clicked. | 353 AddUserView(WrappingButtonView* owner); |
333 AddUserView(UserCard* owner, views::ButtonListener* listener); | |
334 virtual ~AddUserView(); | 354 virtual ~AddUserView(); |
335 | 355 |
336 // Get the anchor view for a message. | 356 // Get the anchor view for a message. |
337 views::View* anchor() { return anchor_; } | 357 views::View* anchor() { return anchor_; } |
338 | 358 |
339 // Overridden from views::ButtonListener. | |
340 virtual void ButtonPressed(views::Button* sender, | |
341 const ui::Event& event) OVERRIDE; | |
342 | |
343 private: | 359 private: |
344 // Overridden from views::View. | 360 // Overridden from views::View. |
345 virtual gfx::Size GetPreferredSize() OVERRIDE; | 361 virtual gfx::Size GetPreferredSize() OVERRIDE; |
346 virtual int GetHeightForWidth(int width) OVERRIDE; | |
347 virtual void Layout() OVERRIDE; | |
348 | 362 |
349 // Create the additional client content for this item. | 363 // Create the additional client content for this item. |
350 void AddContent(); | 364 void AddContent(); |
351 | 365 |
352 // This is the content we create and show. | 366 // This is the content we create and show. |
353 views::View* add_user_; | 367 views::View* add_user_; |
354 | 368 |
355 // This listener will get informed when someone clicks on this button. | |
356 views::ButtonListener* listener_; | |
357 | |
358 // This is the owner view of this item. | 369 // This is the owner view of this item. |
359 UserCard* owner_; | 370 WrappingButtonView* owner_; |
360 | 371 |
361 // The anchor view for targetted bubble messages. | 372 // The anchor view for targetted bubble messages. |
362 views::View* anchor_; | 373 views::View* anchor_; |
363 | 374 |
375 // Whether button enabled. | |
376 bool enabled_; | |
Mr4D (OOO till 08-26)
2014/03/26 16:49:53
Seems not to be needed. Please remove.
| |
377 | |
364 DISALLOW_COPY_AND_ASSIGN(AddUserView); | 378 DISALLOW_COPY_AND_ASSIGN(AddUserView); |
365 }; | 379 }; |
366 | 380 |
381 class UserCardView : public views::View { | |
382 public: | |
383 // |max_width| takes effect only if |login_status| is LOGGED_IN_PUBLIC. | |
384 UserCardView(user::LoginStatus login_status, | |
385 int max_width, | |
386 int multiprofile_index); | |
387 | |
388 private: | |
389 // Creates the content for the retail logged in mode. | |
390 void AddRetailModeUserContent(); | |
391 | |
392 // Creates the content for the public mode. | |
393 void AddPublicModeUserContent(int max_width); | |
394 | |
395 void AddUserContent(user::LoginStatus login_status, int multiprofile_index); | |
Mr4D (OOO till 08-26)
2014/03/26 16:49:53
It would be great to have here a comment what it d
| |
396 | |
397 // Create a user icon representation. | |
398 views::View* CreateIcon(user::LoginStatus login_status, | |
399 int multiprofile_index); | |
400 | |
401 DISALLOW_COPY_AND_ASSIGN(UserCardView); | |
402 }; | |
403 | |
404 class LogoutButton : public TrayPopupLabelButton { | |
405 public: | |
406 LogoutButton(views::ButtonListener* listener, | |
407 const base::string16& text, | |
408 bool placeholder) | |
409 : TrayPopupLabelButton(listener, text), placeholder_(placeholder) { | |
410 SetEnabled(!placeholder_); | |
411 } | |
412 | |
413 private: | |
414 virtual void Paint(gfx::Canvas* canvas) OVERRIDE { | |
415 // Just skip paint if this button used as a placeholder. | |
416 if (!placeholder_) | |
417 TrayPopupLabelButton::Paint(canvas); | |
418 } | |
419 | |
420 bool placeholder_; | |
421 DISALLOW_COPY_AND_ASSIGN(LogoutButton); | |
422 }; | |
423 | |
424 // This detailed view appears after click on user card of primary user if new | |
425 // account managment is enabled. | |
426 class AccountsDetailedView : public TrayDetailsView, | |
427 public ViewClickListener, | |
428 public views::ButtonListener, | |
429 public ash::tray::UserAccountsDelegate::Observer { | |
430 public: | |
431 AccountsDetailedView(TrayUser* owner, user::LoginStatus login_status); | |
432 virtual ~AccountsDetailedView(); | |
433 | |
434 private: | |
435 static const int kAccountsViewVerticalPadding = 12; | |
436 static const int kPrimaryAccountColumnSetID = 0; | |
437 static const int kSecondaryAccountColumnSetID = 1; | |
438 static const int kPaddingBetweenAccounts = 20; | |
439 | |
440 // Overridden from ViewClickListener. | |
441 virtual void OnViewClicked(views::View* sender) OVERRIDE; | |
442 | |
443 // Overridden from views::ButtonListener. | |
444 virtual void ButtonPressed(views::Button* sender, | |
445 const ui::Event& event) OVERRIDE; | |
446 | |
447 // Overridden from ash::tray::UserAccountsDelegate::Observer. | |
448 virtual void AccountListChanged() OVERRIDE; | |
449 | |
450 void AddHeader(user::LoginStatus login_status); | |
451 void AddAccountList(); | |
452 void AddAddAccountButton(); | |
453 void AddFooter(); | |
454 | |
455 void UpdateAccountList(); | |
456 | |
457 views::View* CreateDeleteButton(); | |
458 | |
459 ash::tray::UserAccountsDelegate* delegate_; | |
460 views::View* account_list_; | |
461 views::View* add_account_button_; | |
462 views::View* add_user_button_; | |
463 std::map<views::View*, std::string> delete_button_to_account_id_; | |
464 | |
465 DISALLOW_COPY_AND_ASSIGN(AccountsDetailedView); | |
466 }; | |
467 | |
367 RoundedImageView::RoundedImageView(int corner_radius, bool active_user) | 468 RoundedImageView::RoundedImageView(int corner_radius, bool active_user) |
368 : active_user_(active_user) { | 469 : active_user_(active_user) { |
369 for (int i = 0; i < 4; ++i) | 470 for (int i = 0; i < 4; ++i) |
370 corner_radius_[i] = corner_radius; | 471 corner_radius_[i] = corner_radius; |
371 } | 472 } |
372 | 473 |
373 RoundedImageView::~RoundedImageView() {} | 474 RoundedImageView::~RoundedImageView() {} |
374 | 475 |
375 void RoundedImageView::SetImage(const gfx::ImageSkia& img, | 476 void RoundedImageView::SetImage(const gfx::ImageSkia& img, |
376 const gfx::Size& size) { | 477 const gfx::Size& size) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
419 SkPath path; | 520 SkPath path; |
420 path.addRoundRect(gfx::RectToSkRect(image_bounds), kRadius); | 521 path.addRoundRect(gfx::RectToSkRect(image_bounds), kRadius); |
421 SkPaint paint; | 522 SkPaint paint; |
422 paint.setAntiAlias(true); | 523 paint.setAntiAlias(true); |
423 paint.setXfermodeMode(active_user_ ? SkXfermode::kSrcOver_Mode : | 524 paint.setXfermodeMode(active_user_ ? SkXfermode::kSrcOver_Mode : |
424 SkXfermode::kLuminosity_Mode); | 525 SkXfermode::kLuminosity_Mode); |
425 canvas->DrawImageInPath(resized_, image_bounds.x(), image_bounds.y(), | 526 canvas->DrawImageInPath(resized_, image_bounds.x(), image_bounds.y(), |
426 path, paint); | 527 path, paint); |
427 } | 528 } |
428 | 529 |
429 PublicAccountUserDetails::PublicAccountUserDetails(SystemTrayItem* owner, | 530 PublicAccountUserDetails::PublicAccountUserDetails(int max_width) |
430 int used_width) | |
431 : learn_more_(NULL) { | 531 : learn_more_(NULL) { |
432 const int inner_padding = | 532 const int inner_padding = |
433 kTrayPopupPaddingHorizontal - kTrayPopupPaddingBetweenItems; | 533 kTrayPopupPaddingHorizontal - kTrayPopupPaddingBetweenItems; |
434 const bool rtl = base::i18n::IsRTL(); | 534 const bool rtl = base::i18n::IsRTL(); |
435 SetBorder(views::Border::CreateEmptyBorder(kUserDetailsVerticalPadding, | 535 SetBorder(views::Border::CreateEmptyBorder(kUserDetailsVerticalPadding, |
436 rtl ? 0 : inner_padding, | 536 rtl ? 0 : inner_padding, |
437 kUserDetailsVerticalPadding, | 537 kUserDetailsVerticalPadding, |
438 rtl ? inner_padding : 0)); | 538 rtl ? inner_padding : 0)); |
439 | 539 |
440 // Retrieve the user's display name and wrap it with markers. | 540 // Retrieve the user's display name and wrap it with markers. |
(...skipping 10 matching lines...) Expand all Loading... | |
451 base::i18n::WrapStringWithLTRFormatting(&domain); | 551 base::i18n::WrapStringWithLTRFormatting(&domain); |
452 // Retrieve the label text, inserting the display name and domain. | 552 // Retrieve the label text, inserting the display name and domain. |
453 text_ = l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_PUBLIC_LABEL, | 553 text_ = l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_PUBLIC_LABEL, |
454 display_name, domain); | 554 display_name, domain); |
455 | 555 |
456 learn_more_ = new views::Link(l10n_util::GetStringUTF16(IDS_ASH_LEARN_MORE)); | 556 learn_more_ = new views::Link(l10n_util::GetStringUTF16(IDS_ASH_LEARN_MORE)); |
457 learn_more_->SetUnderline(false); | 557 learn_more_->SetUnderline(false); |
458 learn_more_->set_listener(this); | 558 learn_more_->set_listener(this); |
459 AddChildView(learn_more_); | 559 AddChildView(learn_more_); |
460 | 560 |
461 CalculatePreferredSize(owner, used_width); | 561 CalculatePreferredSize(max_width); |
462 } | 562 } |
463 | 563 |
464 PublicAccountUserDetails::~PublicAccountUserDetails() {} | 564 PublicAccountUserDetails::~PublicAccountUserDetails() {} |
465 | 565 |
466 void PublicAccountUserDetails::Layout() { | 566 void PublicAccountUserDetails::Layout() { |
467 lines_.clear(); | 567 lines_.clear(); |
468 const gfx::Rect contents_area = GetContentsBounds(); | 568 const gfx::Rect contents_area = GetContentsBounds(); |
469 if (contents_area.IsEmpty()) | 569 if (contents_area.IsEmpty()) |
470 return; | 570 return; |
471 | 571 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
542 } | 642 } |
543 views::View::OnPaint(canvas); | 643 views::View::OnPaint(canvas); |
544 } | 644 } |
545 | 645 |
546 void PublicAccountUserDetails::LinkClicked(views::Link* source, | 646 void PublicAccountUserDetails::LinkClicked(views::Link* source, |
547 int event_flags) { | 647 int event_flags) { |
548 DCHECK_EQ(source, learn_more_); | 648 DCHECK_EQ(source, learn_more_); |
549 Shell::GetInstance()->system_tray_delegate()->ShowPublicAccountInfo(); | 649 Shell::GetInstance()->system_tray_delegate()->ShowPublicAccountInfo(); |
550 } | 650 } |
551 | 651 |
552 void PublicAccountUserDetails::CalculatePreferredSize(SystemTrayItem* owner, | 652 void PublicAccountUserDetails::CalculatePreferredSize(int max_allowed_width) { |
553 int used_width) { | |
554 const gfx::FontList font_list; | 653 const gfx::FontList font_list; |
555 const gfx::Size link_size = learn_more_->GetPreferredSize(); | 654 const gfx::Size link_size = learn_more_->GetPreferredSize(); |
556 const int space_width = | 655 const int space_width = |
557 gfx::GetStringWidth(base::ASCIIToUTF16(" "), font_list); | 656 gfx::GetStringWidth(base::ASCIIToUTF16(" "), font_list); |
558 const gfx::Insets insets = GetInsets(); | 657 const gfx::Insets insets = GetInsets(); |
559 views::TrayBubbleView* bubble_view = | 658 int min_width = link_size.width(); |
560 owner->system_tray()->GetSystemBubble()->bubble_view(); | |
561 int min_width = std::max( | |
562 link_size.width(), | |
563 bubble_view->GetPreferredSize().width() - (used_width + insets.width())); | |
564 int max_width = std::min( | 659 int max_width = std::min( |
565 gfx::GetStringWidth(text_, font_list) + space_width + link_size.width(), | 660 gfx::GetStringWidth(text_, font_list) + space_width + link_size.width(), |
566 bubble_view->GetMaximumSize().width() - (used_width + insets.width())); | 661 max_allowed_width - insets.width()); |
567 // Do a binary search for the minimum width that ensures no more than three | 662 // Do a binary search for the minimum width that ensures no more than three |
568 // lines are needed. The lower bound is the minimum of the current bubble | 663 // lines are needed. The lower bound is the minimum of the current bubble |
569 // width and the width of the link (as no wrapping is permitted inside the | 664 // width and the width of the link (as no wrapping is permitted inside the |
570 // link). The upper bound is the maximum of the largest allowed bubble width | 665 // link). The upper bound is the maximum of the largest allowed bubble width |
571 // and the sum of the label text and link widths when put on a single line. | 666 // and the sum of the label text and link widths when put on a single line. |
572 std::vector<base::string16> lines; | 667 std::vector<base::string16> lines; |
573 while (min_width < max_width) { | 668 while (min_width < max_width) { |
574 lines.clear(); | 669 lines.clear(); |
575 const int width = (min_width + max_width) / 2; | 670 const int width = (min_width + max_width) / 2; |
576 const bool too_narrow = | 671 const bool too_narrow = |
(...skipping 18 matching lines...) Expand all Loading... | |
595 if (min_width - gfx::GetStringWidth(lines.back(), font_list) <= | 690 if (min_width - gfx::GetStringWidth(lines.back(), font_list) <= |
596 space_width + link_size.width()) { | 691 space_width + link_size.width()) { |
597 ++line_count; | 692 ++line_count; |
598 } | 693 } |
599 const int line_height = font_list.GetHeight(); | 694 const int line_height = font_list.GetHeight(); |
600 const int link_extra_height = std::max( | 695 const int link_extra_height = std::max( |
601 link_size.height() - learn_more_->GetInsets().top() - line_height, 0); | 696 link_size.height() - learn_more_->GetInsets().top() - line_height, 0); |
602 preferred_size_ = gfx::Size( | 697 preferred_size_ = gfx::Size( |
603 min_width + insets.width(), | 698 min_width + insets.width(), |
604 line_count * line_height + link_extra_height + insets.height()); | 699 line_count * line_height + link_extra_height + insets.height()); |
605 | |
606 bubble_view->SetWidth(preferred_size_.width() + used_width); | |
607 } | 700 } |
608 | 701 |
609 UserCard::UserCard(views::ButtonListener* listener, bool active_user) | 702 WrappingButtonView::WrappingButtonView(views::View* content, |
703 views::ButtonListener* listener, | |
704 bool highlight_on_hover) | |
610 : CustomButton(listener), | 705 : CustomButton(listener), |
611 is_active_user_(active_user), | 706 content_(content), |
707 highlight_on_hover_(highlight_on_hover), | |
612 button_hovered_(false), | 708 button_hovered_(false), |
613 show_border_(false) { | 709 show_border_(false) { |
614 if (is_active_user_) { | 710 set_notify_enter_exit_on_child(true); |
615 set_background( | 711 SetLayoutManager( |
616 views::Background::CreateSolidBackground(kBackgroundColor)); | 712 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0)); |
617 ShowActive(); | 713 AddChildView(content_); |
618 } | 714 ShowActive(); |
619 } | 715 } |
620 | 716 |
621 UserCard::~UserCard() {} | 717 WrappingButtonView::~WrappingButtonView() {} |
622 | 718 |
623 void UserCard::ForceBorderVisible(bool show) { | 719 void WrappingButtonView::ForceBorderVisible(bool show) { |
624 show_border_ = show; | 720 show_border_ = show; |
625 ShowActive(); | 721 ShowActive(); |
626 } | 722 } |
627 | 723 |
628 void UserCard::OnMouseEntered(const ui::MouseEvent& event) { | 724 void WrappingButtonView::OnMouseEntered(const ui::MouseEvent& event) { |
629 if (is_active_user_) { | 725 button_hovered_ = true; |
630 button_hovered_ = true; | 726 ShowActive(); |
631 background()->SetNativeControlColor(kHoverBackgroundColor); | |
632 ShowActive(); | |
633 } | |
634 } | 727 } |
635 | 728 |
636 void UserCard::OnMouseExited(const ui::MouseEvent& event) { | 729 void WrappingButtonView::OnMouseExited(const ui::MouseEvent& event) { |
637 if (is_active_user_) { | 730 button_hovered_ = false; |
638 button_hovered_ = false; | 731 ShowActive(); |
639 background()->SetNativeControlColor(kBackgroundColor); | |
640 ShowActive(); | |
641 } | |
642 } | 732 } |
643 | 733 |
644 void UserCard::ShowActive() { | 734 void WrappingButtonView::ShowActive() { |
645 int width = button_hovered_ || show_border_ ? 1 : 0; | 735 bool border_visible = |
646 SetBorder(views::Border::CreateSolidSidedBorder( | 736 (button_hovered_ && highlight_on_hover_) || show_border_; |
647 width, width, width, 1, kBorderColor)); | 737 SkColor border_color = border_visible ? kBorderColor : SK_ColorTRANSPARENT; |
738 SetBorder(views::Border::CreateSolidBorder(1, border_color)); | |
739 if (highlight_on_hover_) { | |
740 SkColor background_color = | |
741 button_hovered_ ? kHoverBackgroundColor : kBackgroundColor; | |
742 content_->set_background( | |
743 views::Background::CreateSolidBackground(background_color)); | |
744 set_background(views::Background::CreateSolidBackground(background_color)); | |
745 } | |
648 SchedulePaint(); | 746 SchedulePaint(); |
649 } | 747 } |
650 | 748 |
651 UserView::UserView(SystemTrayItem* owner, | 749 UserView::UserView(SystemTrayItem* owner, |
652 user::LoginStatus login, | 750 user::LoginStatus login, |
653 MultiProfileIndex index) | 751 MultiProfileIndex index, |
752 bool for_detailed_view) | |
654 : multiprofile_index_(index), | 753 : multiprofile_index_(index), |
655 user_card_view_(NULL), | 754 user_card_view_(NULL), |
656 owner_(owner), | 755 owner_(owner), |
657 is_user_card_(false), | 756 is_user_card_button_(false), |
658 logout_button_(NULL), | 757 logout_button_(NULL), |
659 add_user_visible_but_disabled_(false) { | 758 add_user_disabled_(false), |
759 for_detailed_view_(for_detailed_view) { | |
660 CHECK_NE(user::LOGGED_IN_NONE, login); | 760 CHECK_NE(user::LOGGED_IN_NONE, login); |
661 if (!index) { | 761 if (!index) { |
662 // Only the logged in user will have a background. All other users will have | 762 // Only the logged in user will have a background. All other users will have |
663 // to allow the TrayPopupContainer highlighting the menu line. | 763 // to allow the TrayPopupContainer highlighting the menu line. |
664 set_background(views::Background::CreateSolidBackground( | 764 set_background(views::Background::CreateSolidBackground( |
665 login == user::LOGGED_IN_PUBLIC ? kPublicAccountBackgroundColor : | 765 login == user::LOGGED_IN_PUBLIC ? kPublicAccountBackgroundColor : |
666 kBackgroundColor)); | 766 kBackgroundColor)); |
667 } | 767 } |
668 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, | 768 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, |
669 kTrayPopupPaddingBetweenItems)); | 769 kTrayPopupPaddingBetweenItems)); |
670 // The logout button must be added before the user card so that the user card | 770 // The logout button must be added before the user card so that the user card |
671 // can correctly calculate the remaining available width. | 771 // can correctly calculate the remaining available width. |
672 // Note that only the current multiprofile user gets a button. | 772 // Note that only the current multiprofile user gets a button. |
673 if (!multiprofile_index_) | 773 if (!multiprofile_index_) |
674 AddLogoutButton(login); | 774 AddLogoutButton(login); |
675 AddUserCard(owner, login); | 775 AddUserCard(login); |
676 } | 776 } |
677 | 777 |
678 UserView::~UserView() {} | 778 UserView::~UserView() {} |
679 | 779 |
680 void UserView::MouseMovedOutOfHost() { | 780 void UserView::MouseMovedOutOfHost() { |
681 popup_message_.reset(); | 781 popup_message_.reset(); |
682 mouse_watcher_.reset(); | 782 mouse_watcher_.reset(); |
683 add_menu_option_.reset(); | 783 add_menu_option_.reset(); |
684 } | 784 } |
685 | 785 |
686 TrayUser::TestState UserView::GetStateForTest() const { | 786 TrayUser::TestState UserView::GetStateForTest() const { |
687 if (add_menu_option_.get()) { | 787 if (add_menu_option_.get()) { |
688 return add_user_visible_but_disabled_ ? TrayUser::ACTIVE_BUT_DISABLED : | 788 return add_user_disabled_ ? TrayUser::ACTIVE_BUT_DISABLED |
689 TrayUser::ACTIVE; | 789 : TrayUser::ACTIVE; |
690 } | 790 } |
691 | 791 |
692 if (!is_user_card_) | 792 if (!is_user_card_button_) |
693 return TrayUser::SHOWN; | 793 return TrayUser::SHOWN; |
694 | 794 |
695 return static_cast<UserCard*>(user_card_view_)->is_hovered_for_test() ? | 795 return static_cast<WrappingButtonView*>(user_card_view_) |
696 TrayUser::HOVERED : TrayUser::SHOWN; | 796 ->is_hovered_for_test() |
797 ? TrayUser::HOVERED | |
798 : TrayUser::SHOWN; | |
697 } | 799 } |
698 | 800 |
699 gfx::Rect UserView::GetBoundsInScreenOfUserButtonForTest() { | 801 gfx::Rect UserView::GetBoundsInScreenOfUserButtonForTest() { |
700 DCHECK(user_card_view_); | 802 DCHECK(user_card_view_); |
701 return user_card_view_->GetBoundsInScreen(); | 803 return user_card_view_->GetBoundsInScreen(); |
702 } | 804 } |
703 | 805 |
704 gfx::Size UserView::GetPreferredSize() { | 806 gfx::Size UserView::GetPreferredSize() { |
705 gfx::Size size = views::View::GetPreferredSize(); | 807 gfx::Size size = views::View::GetPreferredSize(); |
706 // Only the active user panel will be forced to a certain height. | 808 // Only the active user panel will be forced to a certain height. |
(...skipping 12 matching lines...) Expand all Loading... | |
719 gfx::Rect contents_area(GetContentsBounds()); | 821 gfx::Rect contents_area(GetContentsBounds()); |
720 if (user_card_view_ && logout_button_) { | 822 if (user_card_view_ && logout_button_) { |
721 // Give the logout button the space it requests. | 823 // Give the logout button the space it requests. |
722 gfx::Rect logout_area = contents_area; | 824 gfx::Rect logout_area = contents_area; |
723 logout_area.ClampToCenteredSize(logout_button_->GetPreferredSize()); | 825 logout_area.ClampToCenteredSize(logout_button_->GetPreferredSize()); |
724 logout_area.set_x(contents_area.right() - logout_area.width()); | 826 logout_area.set_x(contents_area.right() - logout_area.width()); |
725 | 827 |
726 // Give the remaining space to the user card. | 828 // Give the remaining space to the user card. |
727 gfx::Rect user_card_area = contents_area; | 829 gfx::Rect user_card_area = contents_area; |
728 int remaining_width = contents_area.width() - logout_area.width(); | 830 int remaining_width = contents_area.width() - logout_area.width(); |
729 if (SupportsMultiProfile()) { | 831 if (IsMultiProfileSupported() || IsAccountManagementSupported()) { |
730 // In multiprofile case |user_card_view_| and |logout_button_| have to | 832 // In multiprofile case |user_card_view_| and |logout_button_| have to |
731 // have the same height. | 833 // have the same height. |
732 int y = std::min(user_card_area.y(), logout_area.y()); | 834 int y = std::min(user_card_area.y(), logout_area.y()); |
733 int height = std::max(user_card_area.height(), logout_area.height()); | 835 int height = std::max(user_card_area.height(), logout_area.height()); |
734 logout_area.set_y(y); | 836 logout_area.set_y(y); |
735 logout_area.set_height(height); | 837 logout_area.set_height(height); |
736 user_card_area.set_y(y); | 838 user_card_area.set_y(y); |
737 user_card_area.set_height(height); | 839 user_card_area.set_height(height); |
738 | 840 |
739 // In multiprofile mode we have also to increase the size of the card by | 841 // In multiprofile mode we have also to increase the size of the card by |
(...skipping 18 matching lines...) Expand all Loading... | |
758 } else if (logout_button_) { | 860 } else if (logout_button_) { |
759 logout_button_->SetBoundsRect(contents_area); | 861 logout_button_->SetBoundsRect(contents_area); |
760 } | 862 } |
761 } | 863 } |
762 | 864 |
763 void UserView::ButtonPressed(views::Button* sender, const ui::Event& event) { | 865 void UserView::ButtonPressed(views::Button* sender, const ui::Event& event) { |
764 if (sender == logout_button_) { | 866 if (sender == logout_button_) { |
765 Shell::GetInstance()->metrics()->RecordUserMetricsAction( | 867 Shell::GetInstance()->metrics()->RecordUserMetricsAction( |
766 ash::UMA_STATUS_AREA_SIGN_OUT); | 868 ash::UMA_STATUS_AREA_SIGN_OUT); |
767 Shell::GetInstance()->system_tray_delegate()->SignOut(); | 869 Shell::GetInstance()->system_tray_delegate()->SignOut(); |
768 } else if (sender == user_card_view_ && SupportsMultiProfile()) { | 870 } else if (sender == user_card_view_ && !multiprofile_index_ && |
871 IsAccountManagementSupported()) { | |
872 owner_->TransitionDetailedView(); | |
873 } else if (sender == user_card_view_ && IsMultiProfileSupported()) { | |
769 if (!multiprofile_index_) { | 874 if (!multiprofile_index_) { |
770 ToggleAddUserMenuOption(); | 875 ToggleAddUserMenuOption(); |
771 } else { | 876 } else { |
772 SwitchUser(multiprofile_index_); | 877 SwitchUser(multiprofile_index_); |
773 // Since the user list is about to change the system menu should get | 878 // Since the user list is about to change the system menu should get |
774 // closed. | 879 // closed. |
775 owner_->system_tray()->CloseSystemBubble(); | 880 owner_->system_tray()->CloseSystemBubble(); |
776 } | 881 } |
777 } else if (add_menu_option_.get() && | 882 } else if (add_menu_option_.get() && |
778 sender == add_menu_option_->GetContentsView()) { | 883 sender == add_menu_option_->GetContentsView()) { |
779 // Let the user add another account to the session. | 884 // Let the user add another account to the session. |
780 MultiProfileUMA::RecordSigninUser(MultiProfileUMA::SIGNIN_USER_BY_TRAY); | 885 MultiProfileUMA::RecordSigninUser(MultiProfileUMA::SIGNIN_USER_BY_TRAY); |
781 Shell::GetInstance()->system_tray_delegate()->ShowUserLogin(); | 886 Shell::GetInstance()->system_tray_delegate()->ShowUserLogin(); |
782 owner_->system_tray()->CloseSystemBubble(); | 887 owner_->system_tray()->CloseSystemBubble(); |
783 } else { | 888 } else { |
784 NOTREACHED(); | 889 NOTREACHED(); |
785 } | 890 } |
786 } | 891 } |
787 | 892 |
788 void UserView::AddLogoutButton(user::LoginStatus login) { | 893 void UserView::AddLogoutButton(user::LoginStatus login) { |
789 const base::string16 title = user::GetLocalizedSignOutStringForStatus(login, | 894 const base::string16 title = user::GetLocalizedSignOutStringForStatus(login, |
790 true); | 895 true); |
791 TrayPopupLabelButton* logout_button = new TrayPopupLabelButton(this, title); | 896 TrayPopupLabelButton* logout_button = |
897 new LogoutButton(this, title, for_detailed_view_); | |
792 logout_button->SetAccessibleName(title); | 898 logout_button->SetAccessibleName(title); |
793 logout_button_ = logout_button; | 899 logout_button_ = logout_button; |
794 // In public account mode, the logout button border has a custom color. | 900 // In public account mode, the logout button border has a custom color. |
795 if (login == user::LOGGED_IN_PUBLIC) { | 901 if (login == user::LOGGED_IN_PUBLIC) { |
796 scoped_ptr<TrayPopupLabelButtonBorder> border( | 902 scoped_ptr<TrayPopupLabelButtonBorder> border( |
797 new TrayPopupLabelButtonBorder()); | 903 new TrayPopupLabelButtonBorder()); |
798 border->SetPainter(false, views::Button::STATE_NORMAL, | 904 border->SetPainter(false, views::Button::STATE_NORMAL, |
799 views::Painter::CreateImageGridPainter( | 905 views::Painter::CreateImageGridPainter( |
800 kPublicAccountLogoutButtonBorderImagesNormal)); | 906 kPublicAccountLogoutButtonBorderImagesNormal)); |
801 border->SetPainter(false, views::Button::STATE_HOVERED, | 907 border->SetPainter(false, views::Button::STATE_HOVERED, |
802 views::Painter::CreateImageGridPainter( | 908 views::Painter::CreateImageGridPainter( |
803 kPublicAccountLogoutButtonBorderImagesHovered)); | 909 kPublicAccountLogoutButtonBorderImagesHovered)); |
804 border->SetPainter(false, views::Button::STATE_PRESSED, | 910 border->SetPainter(false, views::Button::STATE_PRESSED, |
805 views::Painter::CreateImageGridPainter( | 911 views::Painter::CreateImageGridPainter( |
806 kPublicAccountLogoutButtonBorderImagesHovered)); | 912 kPublicAccountLogoutButtonBorderImagesHovered)); |
807 logout_button_->SetBorder(border.PassAs<views::Border>()); | 913 logout_button_->SetBorder(border.PassAs<views::Border>()); |
808 } | 914 } |
809 AddChildView(logout_button_); | 915 AddChildView(logout_button_); |
810 } | 916 } |
811 | 917 |
812 void UserView::AddUserCard(SystemTrayItem* owner, user::LoginStatus login) { | 918 void UserView::AddUserCard(user::LoginStatus login) { |
813 // Add padding around the panel. | 919 // Add padding around the panel. |
814 SetBorder(views::Border::CreateEmptyBorder(kUserCardVerticalPadding, | 920 SetBorder(views::Border::CreateEmptyBorder(kUserCardVerticalPadding, |
815 kTrayPopupPaddingHorizontal, | 921 kTrayPopupPaddingHorizontal, |
816 kUserCardVerticalPadding, | 922 kUserCardVerticalPadding, |
817 kTrayPopupPaddingHorizontal)); | 923 kTrayPopupPaddingHorizontal)); |
818 | 924 |
819 if (SupportsMultiProfile() && login != user::LOGGED_IN_RETAIL_MODE) { | 925 views::TrayBubbleView* bubble_view = |
820 user_card_view_ = new UserCard(this, multiprofile_index_ == 0); | 926 owner_->system_tray()->GetSystemBubble()->bubble_view(); |
821 is_user_card_ = true; | 927 int max_card_width = |
822 } else { | 928 bubble_view->GetMaximumSize().width() - |
823 user_card_view_ = new views::View(); | 929 (2 * kTrayPopupPaddingHorizontal + kTrayPopupPaddingBetweenItems); |
824 is_user_card_ = false; | 930 if (logout_button_) |
931 max_card_width -= logout_button_->GetPreferredSize().width(); | |
932 user_card_view_ = | |
933 new UserCardView(login, max_card_width, multiprofile_index_); | |
934 bool clickable = IsMultiProfileSupported() || IsAccountManagementSupported(); | |
935 if (clickable) { | |
936 // To allow the border to start before the icon, reduce the size before and | |
937 // add an inset to the icon to get the spacing. | |
938 if (!multiprofile_index_) { | |
939 SetBorder(views::Border::CreateEmptyBorder( | |
940 kUserCardVerticalPadding, | |
941 kTrayPopupPaddingHorizontal - kTrayUserTileHoverBorderInset, | |
942 kUserCardVerticalPadding, | |
943 kTrayPopupPaddingHorizontal)); | |
944 user_card_view_->SetBorder(views::Border::CreateEmptyBorder( | |
945 0, kTrayUserTileHoverBorderInset, 0, 0)); | |
946 } | |
947 if (!for_detailed_view_) { | |
948 user_card_view_ = | |
949 new WrappingButtonView(user_card_view_, this, !multiprofile_index_); | |
950 } else { | |
951 // We want user card for detailed view to have exactly the same look | |
952 // as user card for default view. That's why we wrap it in a button | |
953 // without click listener and special hover behaviour. | |
954 user_card_view_ = new WrappingButtonView(user_card_view_, NULL, false); | |
955 } | |
956 is_user_card_button_ = true; | |
825 } | 957 } |
826 | |
827 user_card_view_->SetLayoutManager(new views::BoxLayout( | |
828 views::BoxLayout::kHorizontal, 0, 0 , kTrayPopupPaddingBetweenItems)); | |
829 AddChildViewAt(user_card_view_, 0); | 958 AddChildViewAt(user_card_view_, 0); |
830 | 959 // Card for locally managed user can consume more space than currently |
831 if (login == user::LOGGED_IN_RETAIL_MODE) { | 960 // available. In that case we should increase system bubble's width. |
832 AddLoggedInRetailModeUserCardContent(); | 961 if (login == user::LOGGED_IN_PUBLIC) |
833 return; | 962 bubble_view->SetWidth(GetPreferredSize().width()); |
834 } | |
835 | |
836 // The entire user card should trigger hover (the inner items get disabled). | |
837 user_card_view_->SetEnabled(true); | |
838 user_card_view_->set_notify_enter_exit_on_child(true); | |
839 | |
840 if (login == user::LOGGED_IN_PUBLIC) { | |
841 AddLoggedInPublicModeUserCardContent(owner); | |
842 return; | |
843 } | |
844 | |
845 views::View* icon = CreateIconForUserCard(login); | |
846 user_card_view_->AddChildView(icon); | |
847 | |
848 // To allow the border to start before the icon, reduce the size before and | |
849 // add an inset to the icon to get the spacing. | |
850 if (multiprofile_index_ == 0 && SupportsMultiProfile()) { | |
851 icon->SetBorder(views::Border::CreateEmptyBorder( | |
852 0, kTrayUserTileHoverBorderInset, 0, 0)); | |
853 SetBorder(views::Border::CreateEmptyBorder( | |
854 kUserCardVerticalPadding, | |
855 kTrayPopupPaddingHorizontal - kTrayUserTileHoverBorderInset, | |
856 kUserCardVerticalPadding, | |
857 kTrayPopupPaddingHorizontal)); | |
858 } | |
859 SessionStateDelegate* delegate = | |
860 Shell::GetInstance()->session_state_delegate(); | |
861 views::Label* username = NULL; | |
862 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
863 if (!multiprofile_index_) { | |
864 base::string16 user_name_string = | |
865 login == user::LOGGED_IN_GUEST ? | |
866 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_GUEST_LABEL) : | |
867 delegate->GetUserDisplayName(multiprofile_index_); | |
868 if (!user_name_string.empty()) { | |
869 username = new views::Label(user_name_string); | |
870 username->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
871 } | |
872 } | |
873 | |
874 views::Label* additional = NULL; | |
875 if (login != user::LOGGED_IN_GUEST) { | |
876 base::string16 user_email_string = | |
877 login == user::LOGGED_IN_LOCALLY_MANAGED ? | |
878 bundle.GetLocalizedString( | |
879 IDS_ASH_STATUS_TRAY_LOCALLY_MANAGED_LABEL) : | |
880 base::UTF8ToUTF16(delegate->GetUserEmail(multiprofile_index_)); | |
881 if (!user_email_string.empty()) { | |
882 additional = new views::Label(user_email_string); | |
883 additional->SetFontList( | |
884 bundle.GetFontList(ui::ResourceBundle::SmallFont)); | |
885 additional->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
886 } | |
887 } | |
888 | |
889 // Adjust text properties dependent on if it is an active or inactive user. | |
890 if (multiprofile_index_) { | |
891 // Fade the text of non active users to 50%. | |
892 SkColor text_color = additional->enabled_color(); | |
893 text_color = SkColorSetA(text_color, SkColorGetA(text_color) / 2); | |
894 if (additional) | |
895 additional->SetDisabledColor(text_color); | |
896 if (username) | |
897 username->SetDisabledColor(text_color); | |
898 } | |
899 | |
900 if (additional && username) { | |
901 views::View* details = new views::View; | |
902 details->SetLayoutManager(new views::BoxLayout( | |
903 views::BoxLayout::kVertical, 0, kUserDetailsVerticalPadding, 0)); | |
904 details->AddChildView(username); | |
905 details->AddChildView(additional); | |
906 user_card_view_->AddChildView(details); | |
907 } else { | |
908 if (username) | |
909 user_card_view_->AddChildView(username); | |
910 if (additional) | |
911 user_card_view_->AddChildView(additional); | |
912 } | |
913 } | |
914 | |
915 views::View* UserView::CreateIconForUserCard(user::LoginStatus login) { | |
916 RoundedImageView* icon = new RoundedImageView(kProfileRoundedCornerRadius, | |
917 multiprofile_index_ == 0); | |
918 icon->SetEnabled(false); | |
919 if (login == user::LOGGED_IN_GUEST) { | |
920 icon->SetImage(*ui::ResourceBundle::GetSharedInstance(). | |
921 GetImageNamed(IDR_AURA_UBER_TRAY_GUEST_ICON).ToImageSkia(), | |
922 gfx::Size(kUserIconSize, kUserIconSize)); | |
923 } else { | |
924 SessionStateDelegate* delegate = | |
925 Shell::GetInstance()->session_state_delegate(); | |
926 content::BrowserContext* context = delegate->GetBrowserContextByIndex( | |
927 multiprofile_index_); | |
928 icon->SetImage(delegate->GetUserImage(context), | |
929 gfx::Size(kUserIconSize, kUserIconSize)); | |
930 } | |
931 return icon; | |
932 } | |
933 | |
934 void UserView::AddLoggedInRetailModeUserCardContent() { | |
935 views::Label* details = new views::Label; | |
936 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
937 details->SetText( | |
938 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_KIOSK_LABEL)); | |
939 details->SetBorder(views::Border::CreateEmptyBorder(0, 4, 0, 1)); | |
940 details->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
941 user_card_view_->AddChildView(details); | |
942 } | |
943 | |
944 void UserView::AddLoggedInPublicModeUserCardContent(SystemTrayItem* owner) { | |
945 user_card_view_->AddChildView(CreateIconForUserCard(user::LOGGED_IN_PUBLIC)); | |
946 user_card_view_->AddChildView(new PublicAccountUserDetails( | |
947 owner, GetPreferredSize().width() + kTrayPopupPaddingBetweenItems)); | |
948 } | 963 } |
949 | 964 |
950 void UserView::ToggleAddUserMenuOption() { | 965 void UserView::ToggleAddUserMenuOption() { |
951 if (add_menu_option_.get()) { | 966 if (add_menu_option_.get()) { |
952 popup_message_.reset(); | 967 popup_message_.reset(); |
953 mouse_watcher_.reset(); | 968 mouse_watcher_.reset(); |
954 add_menu_option_.reset(); | 969 add_menu_option_.reset(); |
955 return; | 970 return; |
956 } | 971 } |
957 | 972 |
958 // Note: We do not need to install a global event handler to delete this | 973 // Note: We do not need to install a global event handler to delete this |
959 // item since it will destroyed automatically before the menu / user menu item | 974 // item since it will destroyed automatically before the menu / user menu item |
960 // gets destroyed.. | 975 // gets destroyed.. |
961 const SessionStateDelegate* session_state_delegate = | |
962 Shell::GetInstance()->session_state_delegate(); | |
963 add_user_visible_but_disabled_ = | |
964 session_state_delegate->NumberOfLoggedInUsers() >= | |
965 session_state_delegate->GetMaximumNumberOfLoggedInUsers(); | |
966 add_menu_option_.reset(new views::Widget); | 976 add_menu_option_.reset(new views::Widget); |
967 views::Widget::InitParams params; | 977 views::Widget::InitParams params; |
968 params.type = views::Widget::InitParams::TYPE_TOOLTIP; | 978 params.type = views::Widget::InitParams::TYPE_TOOLTIP; |
969 params.keep_on_top = true; | 979 params.keep_on_top = true; |
970 params.context = this->GetWidget()->GetNativeWindow(); | 980 params.context = this->GetWidget()->GetNativeWindow(); |
971 params.accept_events = true; | 981 params.accept_events = true; |
972 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 982 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
973 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 983 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
974 add_menu_option_->Init(params); | 984 add_menu_option_->Init(params); |
975 add_menu_option_->SetOpacity(0xFF); | 985 add_menu_option_->SetOpacity(0xFF); |
976 add_menu_option_->GetNativeWindow()->set_owned_by_parent(false); | 986 add_menu_option_->GetNativeWindow()->set_owned_by_parent(false); |
977 SetShadowType(add_menu_option_->GetNativeView(), | 987 SetShadowType(add_menu_option_->GetNativeView(), |
978 wm::SHADOW_TYPE_NONE); | 988 wm::SHADOW_TYPE_NONE); |
979 | 989 |
980 // Position it below our user card. | 990 // Position it below our user card. |
981 gfx::Rect bounds = user_card_view_->GetBoundsInScreen(); | 991 gfx::Rect bounds = user_card_view_->GetBoundsInScreen(); |
982 bounds.set_y(bounds.y() + bounds.height()); | 992 bounds.set_y(bounds.y() + bounds.height()); |
983 add_menu_option_->SetBounds(bounds); | 993 add_menu_option_->SetBounds(bounds); |
984 | 994 |
985 // Show the content. | 995 // Show the content. |
986 AddUserView* add_user_view = new AddUserView( | |
987 static_cast<UserCard*>(user_card_view_), this); | |
988 add_menu_option_->SetContentsView(add_user_view); | |
989 add_menu_option_->SetAlwaysOnTop(true); | 996 add_menu_option_->SetAlwaysOnTop(true); |
990 add_menu_option_->Show(); | 997 add_menu_option_->Show(); |
991 if (add_user_visible_but_disabled_) { | 998 |
999 AddUserView* add_user_view = | |
1000 new AddUserView(static_cast<WrappingButtonView*>(user_card_view_)); | |
1001 | |
1002 const SessionStateDelegate* delegate = | |
1003 Shell::GetInstance()->session_state_delegate(); | |
1004 add_user_disabled_ = delegate->NumberOfLoggedInUsers() >= | |
1005 delegate->GetMaximumNumberOfLoggedInUsers(); | |
1006 WrappingButtonView* button = | |
1007 add_user_disabled_ ? new WrappingButtonView(add_user_view, NULL, false) | |
1008 : new WrappingButtonView(add_user_view, this, true); | |
1009 button->ForceBorderVisible(true); | |
1010 add_menu_option_->SetContentsView(button); | |
1011 | |
1012 if (add_user_disabled_) { | |
992 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | 1013 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
993 popup_message_.reset(new PopupMessage( | 1014 popup_message_.reset(new PopupMessage( |
994 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAPTION_CANNOT_ADD_USER), | 1015 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAPTION_CANNOT_ADD_USER), |
995 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER), | 1016 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER), |
996 PopupMessage::ICON_WARNING, | 1017 PopupMessage::ICON_WARNING, |
997 add_user_view->anchor(), | 1018 add_user_view->anchor(), |
998 views::BubbleBorder::TOP_LEFT, | 1019 views::BubbleBorder::TOP_LEFT, |
999 gfx::Size(parent()->bounds().width() - kPopupMessageOffset, 0), | 1020 gfx::Size(parent()->bounds().width() - kPopupMessageOffset, 0), |
1000 2 * kPopupMessageOffset)); | 1021 2 * kPopupMessageOffset)); |
1001 } | 1022 } |
1002 // Find the screen area which encloses both elements and sets then a mouse | 1023 // Find the screen area which encloses both elements and sets then a mouse |
1003 // watcher which will close the "menu". | 1024 // watcher which will close the "menu". |
1004 gfx::Rect area = user_card_view_->GetBoundsInScreen(); | 1025 gfx::Rect area = user_card_view_->GetBoundsInScreen(); |
1005 area.set_height(2 * area.height()); | 1026 area.set_height(2 * area.height()); |
1006 mouse_watcher_.reset(new views::MouseWatcher( | 1027 mouse_watcher_.reset(new views::MouseWatcher( |
1007 new UserViewMouseWatcherHost(area), | 1028 new UserViewMouseWatcherHost(area), |
1008 this)); | 1029 this)); |
1009 mouse_watcher_->Start(); | 1030 mouse_watcher_->Start(); |
1010 } | 1031 } |
1011 | 1032 |
1012 bool UserView::SupportsMultiProfile() { | 1033 AddUserView::AddUserView(WrappingButtonView* owner) |
1013 // We do not want to see any multi profile additions to a user view when the | 1034 : add_user_(NULL), owner_(owner), anchor_(NULL) { |
1014 // log in screen is shown. | |
1015 return Shell::GetInstance()->delegate()->IsMultiProfilesEnabled() && | |
1016 !Shell::GetInstance()->session_state_delegate()->IsUserSessionBlocked(); | |
1017 } | |
1018 | |
1019 AddUserView::AddUserView(UserCard* owner, views::ButtonListener* listener) | |
1020 : CustomButton(listener), | |
1021 add_user_(NULL), | |
1022 listener_(listener), | |
1023 owner_(owner), | |
1024 anchor_(NULL) { | |
1025 AddContent(); | 1035 AddContent(); |
1026 owner_->ForceBorderVisible(true); | 1036 owner_->ForceBorderVisible(true); |
1027 } | 1037 } |
1028 | 1038 |
1029 AddUserView::~AddUserView() { | 1039 AddUserView::~AddUserView() { |
1030 owner_->ForceBorderVisible(false); | 1040 owner_->ForceBorderVisible(false); |
1031 } | 1041 } |
1032 | 1042 |
1033 gfx::Size AddUserView::GetPreferredSize() { | 1043 gfx::Size AddUserView::GetPreferredSize() { |
1034 return owner_->bounds().size(); | 1044 return owner_->bounds().size(); |
1035 } | 1045 } |
1036 | 1046 |
1037 int AddUserView::GetHeightForWidth(int width) { | |
1038 return owner_->bounds().size().height(); | |
1039 } | |
1040 | |
1041 void AddUserView::Layout() { | |
1042 gfx::Rect contents_area(GetContentsBounds()); | |
1043 add_user_->SetBoundsRect(contents_area); | |
1044 } | |
1045 | |
1046 void AddUserView::ButtonPressed(views::Button* sender, const ui::Event& event) { | |
1047 if (add_user_ == sender) | |
1048 listener_->ButtonPressed(this, event); | |
1049 else | |
1050 NOTREACHED(); | |
1051 } | |
1052 | |
1053 void AddUserView::AddContent() { | 1047 void AddUserView::AddContent() { |
1054 set_notify_enter_exit_on_child(true); | |
1055 | |
1056 const SessionStateDelegate* delegate = | |
1057 Shell::GetInstance()->session_state_delegate(); | |
1058 bool enable = delegate->NumberOfLoggedInUsers() < | |
1059 delegate->GetMaximumNumberOfLoggedInUsers(); | |
1060 | |
1061 SetLayoutManager(new views::FillLayout()); | 1048 SetLayoutManager(new views::FillLayout()); |
1062 set_background(views::Background::CreateSolidBackground(kBackgroundColor)); | 1049 set_background(views::Background::CreateSolidBackground(kBackgroundColor)); |
1063 | 1050 |
1064 // Add padding around the panel. | 1051 add_user_ = new views::View; |
1065 SetBorder(views::Border::CreateSolidBorder(1, kBorderColor)); | |
1066 | |
1067 add_user_ = new UserCard(this, enable); | |
1068 add_user_->SetBorder(views::Border::CreateEmptyBorder( | 1052 add_user_->SetBorder(views::Border::CreateEmptyBorder( |
1069 kUserCardVerticalPadding, | 1053 kUserCardVerticalPadding, |
1070 kTrayPopupPaddingHorizontal - kTrayUserTileHoverBorderInset, | 1054 kTrayPopupPaddingHorizontal - kTrayUserTileHoverBorderInset, |
1071 kUserCardVerticalPadding, | 1055 kUserCardVerticalPadding, |
1072 kTrayPopupPaddingHorizontal - kTrayUserTileHoverBorderInset)); | 1056 kTrayPopupPaddingHorizontal - kTrayUserTileHoverBorderInset)); |
1073 | 1057 |
1074 add_user_->SetLayoutManager(new views::BoxLayout( | 1058 add_user_->SetLayoutManager(new views::BoxLayout( |
1075 views::BoxLayout::kHorizontal, 0, 0 , kTrayPopupPaddingBetweenItems)); | 1059 views::BoxLayout::kHorizontal, 0, 0, kTrayPopupPaddingBetweenItems)); |
1076 AddChildViewAt(add_user_, 0); | 1060 AddChildViewAt(add_user_, 0); |
1077 | 1061 |
1078 // Add the [+] icon which is also the anchor for messages. | 1062 // Add the [+] icon which is also the anchor for messages. |
1079 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | 1063 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
1080 RoundedImageView* icon = new RoundedImageView(kProfileRoundedCornerRadius, | 1064 RoundedImageView* icon = new RoundedImageView(kProfileRoundedCornerRadius, |
1081 true); | 1065 true); |
1082 anchor_ = icon; | 1066 anchor_ = icon; |
1083 icon->SetImage(*ui::ResourceBundle::GetSharedInstance(). | 1067 icon->SetImage(*ui::ResourceBundle::GetSharedInstance(). |
1084 GetImageNamed(IDR_AURA_UBER_TRAY_ADD_MULTIPROFILE_USER).ToImageSkia(), | 1068 GetImageNamed(IDR_AURA_UBER_TRAY_ADD_MULTIPROFILE_USER).ToImageSkia(), |
1085 gfx::Size(kUserIconSize, kUserIconSize)); | 1069 gfx::Size(kUserIconSize, kUserIconSize)); |
1086 add_user_->AddChildView(icon); | 1070 add_user_->AddChildView(icon); |
1087 | 1071 |
1088 // Add the command text. | 1072 // Add the command text. |
1089 views::Label* command_label = new views::Label( | 1073 views::Label* command_label = new views::Label( |
1090 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); | 1074 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); |
1091 command_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 1075 command_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
1092 add_user_->AddChildView(command_label); | 1076 add_user_->AddChildView(command_label); |
1093 } | 1077 } |
1094 | 1078 |
1079 UserCardView::UserCardView(user::LoginStatus login_status, | |
1080 int max_width, | |
1081 int multiprofile_index) { | |
1082 SetLayoutManager(new views::BoxLayout( | |
1083 views::BoxLayout::kHorizontal, 0, 0, kTrayPopupPaddingBetweenItems)); | |
1084 switch (login_status) { | |
1085 case user::LOGGED_IN_RETAIL_MODE: | |
1086 AddRetailModeUserContent(); | |
1087 break; | |
1088 case user::LOGGED_IN_PUBLIC: | |
1089 AddPublicModeUserContent(max_width); | |
1090 break; | |
1091 default: | |
1092 AddUserContent(login_status, multiprofile_index); | |
1093 break; | |
1094 } | |
1095 } | |
1096 | |
1097 void UserCardView::AddRetailModeUserContent() { | |
1098 views::Label* details = new views::Label; | |
1099 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
1100 details->SetText(bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_KIOSK_LABEL)); | |
1101 details->SetBorder(views::Border::CreateEmptyBorder(0, 4, 0, 1)); | |
1102 details->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
1103 AddChildView(details); | |
1104 } | |
1105 | |
1106 void UserCardView::AddPublicModeUserContent(int max_width) { | |
1107 views::View* icon = CreateIcon(user::LOGGED_IN_PUBLIC, 0); | |
1108 AddChildView(icon); | |
1109 int details_max_width = max_width - icon->GetPreferredSize().width() - | |
1110 kTrayPopupPaddingBetweenItems; | |
1111 AddChildView(new PublicAccountUserDetails(details_max_width)); | |
1112 } | |
1113 | |
1114 void UserCardView::AddUserContent(user::LoginStatus login_status, | |
1115 int multiprofile_index) { | |
1116 views::View* icon = CreateIcon(login_status, multiprofile_index); | |
1117 AddChildView(icon); | |
1118 views::Label* username = NULL; | |
1119 SessionStateDelegate* delegate = | |
1120 Shell::GetInstance()->session_state_delegate(); | |
1121 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
1122 if (!multiprofile_index) { | |
1123 base::string16 user_name_string = | |
1124 login_status == user::LOGGED_IN_GUEST | |
1125 ? bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_GUEST_LABEL) | |
1126 : delegate->GetUserDisplayName(multiprofile_index); | |
1127 if (user_name_string.empty() && IsAccountManagementSupported()) | |
1128 user_name_string = | |
1129 base::ASCIIToUTF16(delegate->GetUserEmail(multiprofile_index)); | |
1130 if (!user_name_string.empty()) { | |
1131 username = new views::Label(user_name_string); | |
1132 username->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
1133 } | |
1134 } | |
1135 | |
1136 views::Label* additional = NULL; | |
1137 if (login_status != user::LOGGED_IN_GUEST && | |
1138 (multiprofile_index || !IsAccountManagementSupported())) { | |
1139 base::string16 user_email_string = | |
1140 login_status == user::LOGGED_IN_LOCALLY_MANAGED | |
1141 ? bundle.GetLocalizedString( | |
1142 IDS_ASH_STATUS_TRAY_LOCALLY_MANAGED_LABEL) | |
1143 : base::UTF8ToUTF16(delegate->GetUserEmail(multiprofile_index)); | |
1144 if (!user_email_string.empty()) { | |
1145 additional = new views::Label(user_email_string); | |
1146 additional->SetFontList( | |
1147 bundle.GetFontList(ui::ResourceBundle::SmallFont)); | |
1148 additional->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
1149 } | |
1150 } | |
1151 | |
1152 // Adjust text properties dependent on if it is an active or inactive user. | |
1153 if (multiprofile_index) { | |
1154 // Fade the text of non active users to 50%. | |
1155 SkColor text_color = additional->enabled_color(); | |
1156 text_color = SkColorSetA(text_color, SkColorGetA(text_color) / 2); | |
1157 if (additional) | |
1158 additional->SetDisabledColor(text_color); | |
1159 if (username) | |
1160 username->SetDisabledColor(text_color); | |
1161 } | |
1162 | |
1163 if (additional && username) { | |
1164 views::View* details = new views::View; | |
1165 details->SetLayoutManager(new views::BoxLayout( | |
1166 views::BoxLayout::kVertical, 0, kUserDetailsVerticalPadding, 0)); | |
1167 details->AddChildView(username); | |
1168 details->AddChildView(additional); | |
1169 AddChildView(details); | |
1170 } else { | |
1171 if (username) | |
1172 AddChildView(username); | |
1173 if (additional) | |
1174 AddChildView(additional); | |
1175 } | |
1176 } | |
1177 | |
1178 views::View* UserCardView::CreateIcon(user::LoginStatus login_status, | |
1179 int multiprofile_index) { | |
1180 RoundedImageView* icon = new RoundedImageView(kProfileRoundedCornerRadius, | |
1181 multiprofile_index == 0); | |
1182 if (login_status == user::LOGGED_IN_GUEST) { | |
1183 icon->SetImage(*ui::ResourceBundle::GetSharedInstance() | |
1184 .GetImageNamed(IDR_AURA_UBER_TRAY_GUEST_ICON) | |
1185 .ToImageSkia(), | |
1186 gfx::Size(kUserIconSize, kUserIconSize)); | |
1187 } else { | |
1188 SessionStateDelegate* delegate = | |
1189 Shell::GetInstance()->session_state_delegate(); | |
1190 content::BrowserContext* context = | |
1191 delegate->GetBrowserContextByIndex(multiprofile_index); | |
1192 icon->SetImage(delegate->GetUserImage(context), | |
1193 gfx::Size(kUserIconSize, kUserIconSize)); | |
1194 } | |
1195 return icon; | |
1196 } | |
1197 | |
1198 AccountsDetailedView::AccountsDetailedView(TrayUser* owner, | |
1199 user::LoginStatus login_status) | |
1200 : TrayDetailsView(owner), | |
1201 delegate_(NULL), | |
1202 account_list_(NULL), | |
1203 add_account_button_(NULL), | |
1204 add_user_button_(NULL) { | |
1205 std::string user_id = | |
1206 Shell::GetInstance()->session_state_delegate()->GetUserID(0); | |
1207 delegate_ = | |
1208 Shell::GetInstance()->system_tray_delegate()->GetUserAccountsDelegate( | |
1209 user_id); | |
1210 delegate_->AddObserver(this); | |
1211 AddHeader(login_status); | |
1212 CreateScrollableList(); | |
1213 AddAccountList(); | |
1214 AddAddAccountButton(); | |
1215 AddFooter(); | |
1216 } | |
1217 | |
1218 AccountsDetailedView::~AccountsDetailedView() { | |
1219 delegate_->RemoveObserver(this); | |
1220 } | |
1221 | |
1222 void AccountsDetailedView::OnViewClicked(views::View* sender) { | |
1223 if (sender == footer()->content()) | |
1224 TransitionToDefaultView(); | |
1225 else if (sender == add_account_button_) | |
1226 delegate_->LaunchAddAccountDialog(); | |
1227 else | |
1228 NOTREACHED(); | |
1229 } | |
1230 | |
1231 void AccountsDetailedView::ButtonPressed(views::Button* sender, | |
1232 const ui::Event& event) { | |
1233 std::map<views::View*, std::string>::iterator it = | |
1234 delete_button_to_account_id_.find(sender); | |
1235 if (it != delete_button_to_account_id_.end()) { | |
1236 delegate_->DeleteAccount(it->second); | |
1237 } else if (add_user_button_ && add_user_button_ == sender) { | |
1238 MultiProfileUMA::RecordSigninUser(MultiProfileUMA::SIGNIN_USER_BY_TRAY); | |
1239 Shell::GetInstance()->system_tray_delegate()->ShowUserLogin(); | |
1240 owner()->system_tray()->CloseSystemBubble(); | |
1241 } else { | |
1242 NOTREACHED(); | |
1243 } | |
1244 } | |
1245 | |
1246 void AccountsDetailedView::AccountListChanged() { UpdateAccountList(); } | |
1247 | |
1248 void AccountsDetailedView::AddHeader(user::LoginStatus login_status) { | |
1249 views::View* user_view_container = new views::View; | |
1250 user_view_container->SetLayoutManager( | |
1251 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); | |
1252 user_view_container->SetBorder( | |
1253 views::Border::CreateSolidSidedBorder(0, 0, 1, 0, kBorderLightColor)); | |
1254 user_view_container->AddChildView( | |
1255 new tray::UserView(owner(), login_status, 0, true)); | |
1256 AddChildView(user_view_container); | |
1257 } | |
1258 | |
1259 void AccountsDetailedView::AddAccountList() { | |
1260 scroll_content()->SetBorder( | |
1261 views::Border::CreateEmptyBorder(kAccountsViewVerticalPadding, | |
1262 kTrayPopupPaddingHorizontal, | |
1263 kAccountsViewVerticalPadding, | |
1264 kTrayPopupPaddingHorizontal)); | |
1265 views::Label* account_list_title = new views::Label( | |
1266 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ACCOUNT_LIST_TITLE)); | |
1267 account_list_title->SetEnabledColor(SkColorSetARGB(0x7f, 0, 0, 0)); | |
1268 account_list_title->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
1269 scroll_content()->AddChildView(account_list_title); | |
1270 account_list_ = new views::View(); | |
1271 UpdateAccountList(); | |
1272 scroll_content()->AddChildView(account_list_); | |
1273 } | |
1274 | |
1275 void AccountsDetailedView::AddAddAccountButton() { | |
1276 SessionStateDelegate* session_state_delegate = | |
1277 Shell::GetInstance()->session_state_delegate(); | |
1278 HoverHighlightView* add_account_button = new HoverHighlightView(this); | |
1279 base::string16 user_name = session_state_delegate->GetUserGivenName(0); | |
1280 if (user_name.empty()) | |
1281 user_name = session_state_delegate->GetUserDisplayName(0); | |
1282 if (user_name.empty()) | |
1283 user_name = base::ASCIIToUTF16(session_state_delegate->GetUserEmail(0)); | |
1284 add_account_button->AddLabel( | |
1285 l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_ADD_ACCOUNT_LABEL, | |
1286 user_name), | |
1287 gfx::ALIGN_CENTER, | |
1288 gfx::Font::NORMAL); | |
1289 AddChildView(add_account_button); | |
1290 add_account_button_ = add_account_button; | |
1291 } | |
1292 | |
1293 void AccountsDetailedView::AddFooter() { | |
1294 CreateSpecialRow(IDS_ASH_STATUS_TRAY_ACCOUNTS_TITLE, this); | |
1295 if (!IsMultiProfileSupported()) | |
1296 return; | |
1297 TrayPopupHeaderButton* add_user_button = | |
1298 new TrayPopupHeaderButton(this, | |
1299 IDR_AURA_UBER_TRAY_NETWORK_INFO, | |
1300 IDR_AURA_UBER_TRAY_NETWORK_INFO, | |
1301 IDR_AURA_UBER_TRAY_NETWORK_INFO_HOVER, | |
1302 IDR_AURA_UBER_TRAY_NETWORK_INFO_HOVER, | |
1303 IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT); | |
1304 add_user_button->SetTooltipText( | |
1305 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); | |
1306 footer()->AddButton(add_user_button); | |
1307 add_user_button_ = add_user_button; | |
1308 } | |
1309 | |
1310 void AccountsDetailedView::UpdateAccountList() { | |
1311 // Clear existing view. | |
1312 delete_button_to_account_id_.clear(); | |
1313 account_list_->RemoveAllChildViews(true); | |
1314 | |
1315 // Configuring layout manager. | |
1316 views::GridLayout* layout = new views::GridLayout(account_list_); | |
1317 account_list_->SetLayoutManager(layout); | |
1318 views::ColumnSet* primary_account_row = | |
1319 layout->AddColumnSet(kPrimaryAccountColumnSetID); | |
1320 primary_account_row->AddColumn(views::GridLayout::LEADING, | |
1321 views::GridLayout::BASELINE, | |
1322 1.0, | |
1323 views::GridLayout::USE_PREF, | |
1324 0, | |
1325 0); | |
1326 views::ColumnSet* secondary_account_row = | |
1327 layout->AddColumnSet(kSecondaryAccountColumnSetID); | |
1328 secondary_account_row->AddColumn(views::GridLayout::FILL, | |
1329 views::GridLayout::BASELINE, | |
1330 1.0, | |
1331 views::GridLayout::USE_PREF, | |
1332 0, | |
1333 0); | |
1334 secondary_account_row->AddPaddingColumn(0.0, kTrayPopupPaddingBetweenItems); | |
1335 secondary_account_row->AddColumn(views::GridLayout::FILL, | |
1336 views::GridLayout::BASELINE, | |
1337 0.0, | |
1338 views::GridLayout::USE_PREF, | |
1339 0, | |
1340 0); | |
1341 | |
1342 // Adding primary account. | |
1343 layout->AddPaddingRow(0.0, kPaddingBetweenAccounts); | |
1344 layout->StartRow(0.0, kPrimaryAccountColumnSetID); | |
1345 const std::string& primary_account = delegate_->GetPrimaryAccount(); | |
1346 views::Label* primary_account_label = | |
1347 new views::Label(l10n_util::GetStringFUTF16( | |
1348 IDS_ASH_STATUS_TRAY_PRIMARY_ACCOUNT_LABEL, | |
1349 base::ASCIIToUTF16( | |
1350 delegate_->GetAccountDisplayName(primary_account)))); | |
1351 layout->AddView(primary_account_label); | |
1352 | |
1353 // Adding secondary accounts. | |
1354 const std::vector<std::string>& secondary_accounts = | |
1355 delegate_->GetSecondaryAccountsList(); | |
1356 for (size_t i = 0; i < secondary_accounts.size(); ++i) { | |
1357 layout->AddPaddingRow(0.0, kPaddingBetweenAccounts); | |
1358 layout->StartRow(0.0, kSecondaryAccountColumnSetID); | |
1359 const std::string& account_id = secondary_accounts[i]; | |
1360 views::Label* account_label = new views::Label( | |
1361 base::ASCIIToUTF16(delegate_->GetAccountDisplayName(account_id))); | |
1362 account_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
1363 layout->AddView(account_label); | |
1364 views::View* delete_button = CreateDeleteButton(); | |
1365 delete_button_to_account_id_[delete_button] = account_id; | |
1366 layout->AddView(delete_button); | |
1367 } | |
1368 | |
1369 scroll_content()->SizeToPreferredSize(); | |
1370 scroller()->Layout(); | |
1371 } | |
1372 | |
1373 views::View* AccountsDetailedView::CreateDeleteButton() { | |
1374 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
1375 views::ImageButton* delete_button = new views::ImageButton(this); | |
1376 delete_button->SetImage(views::Button::STATE_NORMAL, | |
1377 rb.GetImageNamed(IDR_CLOSE_2).ToImageSkia()); | |
1378 delete_button->SetImage(views::Button::STATE_HOVERED, | |
1379 rb.GetImageNamed(IDR_CLOSE_2_H).ToImageSkia()); | |
1380 delete_button->SetImage(views::Button::STATE_PRESSED, | |
1381 rb.GetImageNamed(IDR_CLOSE_2_P).ToImageSkia()); | |
1382 return delete_button; | |
1383 } | |
1384 | |
1095 } // namespace tray | 1385 } // namespace tray |
1096 | 1386 |
1097 TrayUser::TrayUser(SystemTray* system_tray, MultiProfileIndex index) | 1387 TrayUser::TrayUser(SystemTray* system_tray, MultiProfileIndex index) |
1098 : SystemTrayItem(system_tray), | 1388 : SystemTrayItem(system_tray), |
1099 multiprofile_index_(index), | 1389 multiprofile_index_(index), |
1100 user_(NULL), | 1390 user_(NULL), |
1101 layout_view_(NULL), | 1391 layout_view_(NULL), |
1102 avatar_(NULL), | 1392 avatar_(NULL), |
1103 label_(NULL) { | 1393 label_(NULL) { |
1104 Shell::GetInstance()->system_tray_notifier()->AddUserObserver(this); | 1394 Shell::GetInstance()->system_tray_notifier()->AddUserObserver(this); |
(...skipping 22 matching lines...) Expand all Loading... | |
1127 return user_->GetBoundsInScreenOfUserButtonForTest(); | 1417 return user_->GetBoundsInScreenOfUserButtonForTest(); |
1128 } | 1418 } |
1129 | 1419 |
1130 void TrayUser::UpdateAfterLoginStatusChangeForTest(user::LoginStatus status) { | 1420 void TrayUser::UpdateAfterLoginStatusChangeForTest(user::LoginStatus status) { |
1131 UpdateAfterLoginStatusChange(status); | 1421 UpdateAfterLoginStatusChange(status); |
1132 } | 1422 } |
1133 | 1423 |
1134 views::View* TrayUser::CreateTrayView(user::LoginStatus status) { | 1424 views::View* TrayUser::CreateTrayView(user::LoginStatus status) { |
1135 CHECK(layout_view_ == NULL); | 1425 CHECK(layout_view_ == NULL); |
1136 | 1426 |
1137 layout_view_ = new views::View(); | 1427 layout_view_ = new views::View; |
1138 layout_view_->SetLayoutManager( | 1428 layout_view_->SetLayoutManager( |
1139 new views::BoxLayout(views::BoxLayout::kHorizontal, | 1429 new views::BoxLayout(views::BoxLayout::kHorizontal, |
1140 0, 0, kUserLabelToIconPadding)); | 1430 0, 0, kUserLabelToIconPadding)); |
1141 UpdateAfterLoginStatusChange(status); | 1431 UpdateAfterLoginStatusChange(status); |
1142 return layout_view_; | 1432 return layout_view_; |
1143 } | 1433 } |
1144 | 1434 |
1145 views::View* TrayUser::CreateDefaultView(user::LoginStatus status) { | 1435 views::View* TrayUser::CreateDefaultView(user::LoginStatus status) { |
1146 if (status == user::LOGGED_IN_NONE) | 1436 if (status == user::LOGGED_IN_NONE) |
1147 return NULL; | 1437 return NULL; |
1148 const SessionStateDelegate* session_state_delegate = | 1438 const SessionStateDelegate* session_state_delegate = |
1149 Shell::GetInstance()->session_state_delegate(); | 1439 Shell::GetInstance()->session_state_delegate(); |
1150 | 1440 |
1151 // If the screen is locked show only the currently active user. | 1441 // If the screen is locked show only the currently active user. |
1152 if (multiprofile_index_ && session_state_delegate->IsUserSessionBlocked()) | 1442 if (multiprofile_index_ && session_state_delegate->IsUserSessionBlocked()) |
1153 return NULL; | 1443 return NULL; |
1154 | 1444 |
1155 CHECK(user_ == NULL); | 1445 CHECK(user_ == NULL); |
1156 | 1446 |
1157 int logged_in_users = session_state_delegate->NumberOfLoggedInUsers(); | 1447 int logged_in_users = session_state_delegate->NumberOfLoggedInUsers(); |
1158 | 1448 |
1159 // Do not show more UserView's then there are logged in users. | 1449 // Do not show more UserView's then there are logged in users. |
1160 if (multiprofile_index_ >= logged_in_users) | 1450 if (multiprofile_index_ >= logged_in_users) |
1161 return NULL; | 1451 return NULL; |
1162 | 1452 |
1163 user_ = new tray::UserView(this, status, multiprofile_index_); | 1453 user_ = new tray::UserView(this, status, multiprofile_index_, false); |
1164 return user_; | 1454 return user_; |
1165 } | 1455 } |
1166 | 1456 |
1167 views::View* TrayUser::CreateDetailedView(user::LoginStatus status) { | 1457 views::View* TrayUser::CreateDetailedView(user::LoginStatus status) { |
1168 return NULL; | 1458 return new tray::AccountsDetailedView(this, status); |
1169 } | 1459 } |
1170 | 1460 |
1171 void TrayUser::DestroyTrayView() { | 1461 void TrayUser::DestroyTrayView() { |
1172 layout_view_ = NULL; | 1462 layout_view_ = NULL; |
1173 avatar_ = NULL; | 1463 avatar_ = NULL; |
1174 label_ = NULL; | 1464 label_ = NULL; |
1175 } | 1465 } |
1176 | 1466 |
1177 void TrayUser::DestroyDefaultView() { | 1467 void TrayUser::DestroyDefaultView() { |
1178 user_ = NULL; | 1468 user_ = NULL; |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1360 internal::GetRootWindowController( | 1650 internal::GetRootWindowController( |
1361 system_tray()->GetWidget()->GetNativeWindow()->GetRootWindow()); | 1651 system_tray()->GetWidget()->GetNativeWindow()->GetRootWindow()); |
1362 if (controller && controller->shelf()) { | 1652 if (controller && controller->shelf()) { |
1363 UpdateAfterShelfAlignmentChange( | 1653 UpdateAfterShelfAlignmentChange( |
1364 controller->GetShelfLayoutManager()->GetAlignment()); | 1654 controller->GetShelfLayoutManager()->GetAlignment()); |
1365 } | 1655 } |
1366 } | 1656 } |
1367 | 1657 |
1368 } // namespace internal | 1658 } // namespace internal |
1369 } // namespace ash | 1659 } // namespace ash |
OLD | NEW |