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