| 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> | |
| 8 #include <climits> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "ash/ash_switches.h" | 7 #include "ash/ash_switches.h" |
| 12 #include "ash/metrics/user_metrics_recorder.h" | |
| 13 #include "ash/multi_profile_uma.h" | |
| 14 #include "ash/popup_message.h" | |
| 15 #include "ash/root_window_controller.h" | 8 #include "ash/root_window_controller.h" |
| 16 #include "ash/session_state_delegate.h" | 9 #include "ash/session_state_delegate.h" |
| 17 #include "ash/shelf/shelf_layout_manager.h" | 10 #include "ash/shelf/shelf_layout_manager.h" |
| 18 #include "ash/shell.h" | |
| 19 #include "ash/shell_delegate.h" | 11 #include "ash/shell_delegate.h" |
| 20 #include "ash/system/tray/system_tray.h" | 12 #include "ash/system/tray/system_tray.h" |
| 21 #include "ash/system/tray/system_tray_delegate.h" | |
| 22 #include "ash/system/tray/system_tray_notifier.h" | 13 #include "ash/system/tray/system_tray_notifier.h" |
| 23 #include "ash/system/tray/tray_constants.h" | 14 #include "ash/system/tray/tray_constants.h" |
| 24 #include "ash/system/tray/tray_item_view.h" | 15 #include "ash/system/tray/tray_item_view.h" |
| 25 #include "ash/system/tray/tray_popup_label_button.h" | |
| 26 #include "ash/system/tray/tray_popup_label_button_border.h" | |
| 27 #include "ash/system/tray/tray_utils.h" | 16 #include "ash/system/tray/tray_utils.h" |
| 28 #include "base/i18n/rtl.h" | 17 #include "ash/system/user/accounts_detailed_view.h" |
| 18 #include "ash/system/user/rounded_image_view.h" |
| 19 #include "ash/system/user/user_view.h" |
| 29 #include "base/logging.h" | 20 #include "base/logging.h" |
| 30 #include "base/memory/scoped_vector.h" | |
| 31 #include "base/strings/string16.h" | 21 #include "base/strings/string16.h" |
| 32 #include "base/strings/string_util.h" | |
| 33 #include "base/strings/utf_string_conversions.h" | |
| 34 #include "grit/ash_resources.h" | |
| 35 #include "grit/ash_strings.h" | 22 #include "grit/ash_strings.h" |
| 36 #include "skia/ext/image_operations.h" | |
| 37 #include "third_party/skia/include/core/SkCanvas.h" | |
| 38 #include "third_party/skia/include/core/SkPaint.h" | |
| 39 #include "third_party/skia/include/core/SkPath.h" | |
| 40 #include "ui/aura/window.h" | 23 #include "ui/aura/window.h" |
| 41 #include "ui/base/l10n/l10n_util.h" | 24 #include "ui/base/l10n/l10n_util.h" |
| 42 #include "ui/base/resource/resource_bundle.h" | |
| 43 #include "ui/gfx/canvas.h" | |
| 44 #include "ui/gfx/font_list.h" | |
| 45 #include "ui/gfx/image/image.h" | 25 #include "ui/gfx/image/image.h" |
| 46 #include "ui/gfx/image/image_skia_operations.h" | |
| 47 #include "ui/gfx/insets.h" | |
| 48 #include "ui/gfx/range/range.h" | |
| 49 #include "ui/gfx/rect.h" | |
| 50 #include "ui/gfx/render_text.h" | |
| 51 #include "ui/gfx/size.h" | |
| 52 #include "ui/gfx/skia_util.h" | |
| 53 #include "ui/gfx/text_elider.h" | |
| 54 #include "ui/gfx/text_utils.h" | |
| 55 #include "ui/views/border.h" | 26 #include "ui/views/border.h" |
| 56 #include "ui/views/bubble/tray_bubble_view.h" | |
| 57 #include "ui/views/controls/button/button.h" | |
| 58 #include "ui/views/controls/button/custom_button.h" | |
| 59 #include "ui/views/controls/image_view.h" | |
| 60 #include "ui/views/controls/label.h" | 27 #include "ui/views/controls/label.h" |
| 61 #include "ui/views/controls/link.h" | |
| 62 #include "ui/views/controls/link_listener.h" | |
| 63 #include "ui/views/layout/box_layout.h" | 28 #include "ui/views/layout/box_layout.h" |
| 64 #include "ui/views/layout/fill_layout.h" | |
| 65 #include "ui/views/mouse_watcher.h" | |
| 66 #include "ui/views/painter.h" | |
| 67 #include "ui/views/view.h" | 29 #include "ui/views/view.h" |
| 68 #include "ui/views/widget/widget.h" | 30 #include "ui/views/widget/widget.h" |
| 69 #include "ui/wm/core/shadow_types.h" | |
| 70 | 31 |
| 71 namespace { | 32 namespace { |
| 72 | 33 |
| 73 const int kUserDetailsVerticalPadding = 5; | |
| 74 const int kUserCardVerticalPadding = 10; | |
| 75 const int kProfileRoundedCornerRadius = 2; | |
| 76 const int kUserIconSize = 27; | |
| 77 const int kUserIconLargeSize = 32; | |
| 78 const int kUserIconLargeCornerRadius = 2; | |
| 79 const int kUserLabelToIconPadding = 5; | 34 const int kUserLabelToIconPadding = 5; |
| 80 | 35 |
| 81 // When a hover border is used, it is starting this many pixels before the icon | 36 const int kTrayAvatarLargeSize = 32; |
| 82 // position. | 37 const int kTrayAvatarLargeCornerRadius = 2; |
| 83 const int kTrayUserTileHoverBorderInset = 10; | |
| 84 | |
| 85 // The border color of the user button. | |
| 86 const SkColor kBorderColor = 0xffdcdcdc; | |
| 87 | |
| 88 // The invisible word joiner character, used as a marker to indicate the start | |
| 89 // and end of the user's display name in the public account user card's text. | |
| 90 const base::char16 kDisplayNameMark[] = { 0x2060, 0 }; | |
| 91 | |
| 92 const int kPublicAccountLogoutButtonBorderImagesNormal[] = { | |
| 93 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | |
| 94 IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND, | |
| 95 IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND, | |
| 96 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | |
| 97 IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND, | |
| 98 IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND, | |
| 99 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | |
| 100 IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND, | |
| 101 IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND, | |
| 102 }; | |
| 103 | |
| 104 const int kPublicAccountLogoutButtonBorderImagesHovered[] = { | |
| 105 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | |
| 106 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | |
| 107 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | |
| 108 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | |
| 109 IDR_AURA_TRAY_POPUP_LABEL_BUTTON_HOVER_BACKGROUND, | |
| 110 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | |
| 111 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | |
| 112 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | |
| 113 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | |
| 114 }; | |
| 115 | |
| 116 // Offsetting the popup message relative to the tray menu. | |
| 117 const int kPopupMessageOffset = 25; | |
| 118 | |
| 119 // Switch to a user with the given |user_index|. | |
| 120 void SwitchUser(ash::MultiProfileIndex user_index) { | |
| 121 // Do not switch users when the log screen is presented. | |
| 122 if (ash::Shell::GetInstance()->session_state_delegate()-> | |
| 123 IsUserSessionBlocked()) | |
| 124 return; | |
| 125 | |
| 126 DCHECK(user_index > 0); | |
| 127 ash::SessionStateDelegate* delegate = | |
| 128 ash::Shell::GetInstance()->session_state_delegate(); | |
| 129 ash::MultiProfileUMA::RecordSwitchActiveUser( | |
| 130 ash::MultiProfileUMA::SWITCH_ACTIVE_USER_BY_TRAY); | |
| 131 delegate->SwitchActiveUser(delegate->GetUserID(user_index)); | |
| 132 } | |
| 133 | 38 |
| 134 } // namespace | 39 } // namespace |
| 135 | 40 |
| 136 namespace ash { | 41 namespace ash { |
| 137 namespace tray { | |
| 138 | |
| 139 // A custom image view with rounded edges. | |
| 140 class RoundedImageView : public views::View { | |
| 141 public: | |
| 142 // Constructs a new rounded image view with rounded corners of radius | |
| 143 // |corner_radius|. If |active_user| is set, the icon will be drawn in | |
| 144 // full colors - otherwise it will fade into the background. | |
| 145 RoundedImageView(int corner_radius, bool active_user); | |
| 146 virtual ~RoundedImageView(); | |
| 147 | |
| 148 // Set the image that should be displayed. The image contents is copied to the | |
| 149 // receiver's image. | |
| 150 void SetImage(const gfx::ImageSkia& img, const gfx::Size& size); | |
| 151 | |
| 152 // Set the radii of the corners independently. | |
| 153 void SetCornerRadii(int top_left, | |
| 154 int top_right, | |
| 155 int bottom_right, | |
| 156 int bottom_left); | |
| 157 | |
| 158 private: | |
| 159 // Overridden from views::View. | |
| 160 virtual gfx::Size GetPreferredSize() OVERRIDE; | |
| 161 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; | |
| 162 | |
| 163 gfx::ImageSkia image_; | |
| 164 gfx::ImageSkia resized_; | |
| 165 gfx::Size image_size_; | |
| 166 int corner_radius_[4]; | |
| 167 | |
| 168 // True if the given user is the active user and the icon should get | |
| 169 // painted as active. | |
| 170 bool active_user_; | |
| 171 | |
| 172 DISALLOW_COPY_AND_ASSIGN(RoundedImageView); | |
| 173 }; | |
| 174 | |
| 175 // The user details shown in public account mode. This is essentially a label | |
| 176 // but with custom painting code as the text is styled with multiple colors and | |
| 177 // contains a link. | |
| 178 class PublicAccountUserDetails : public views::View, | |
| 179 public views::LinkListener { | |
| 180 public: | |
| 181 PublicAccountUserDetails(SystemTrayItem* owner, int used_width); | |
| 182 virtual ~PublicAccountUserDetails(); | |
| 183 | |
| 184 private: | |
| 185 // Overridden from views::View. | |
| 186 virtual void Layout() OVERRIDE; | |
| 187 virtual gfx::Size GetPreferredSize() OVERRIDE; | |
| 188 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; | |
| 189 | |
| 190 // Overridden from views::LinkListener. | |
| 191 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; | |
| 192 | |
| 193 // Calculate a preferred size that ensures the label text and the following | |
| 194 // link do not wrap over more than three lines in total for aesthetic reasons | |
| 195 // if possible. | |
| 196 void CalculatePreferredSize(SystemTrayItem* owner, int used_width); | |
| 197 | |
| 198 base::string16 text_; | |
| 199 views::Link* learn_more_; | |
| 200 gfx::Size preferred_size_; | |
| 201 ScopedVector<gfx::RenderText> lines_; | |
| 202 | |
| 203 DISALLOW_COPY_AND_ASSIGN(PublicAccountUserDetails); | |
| 204 }; | |
| 205 | |
| 206 // The button which holds the user card in case of multi profile. | |
| 207 class UserCard : public views::CustomButton { | |
| 208 public: | |
| 209 UserCard(views::ButtonListener* listener, bool active_user); | |
| 210 virtual ~UserCard(); | |
| 211 | |
| 212 // Called when the border should remain even in the non highlighted state. | |
| 213 void ForceBorderVisible(bool show); | |
| 214 | |
| 215 // Overridden from views::View | |
| 216 virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; | |
| 217 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; | |
| 218 | |
| 219 // Check if the item is hovered. | |
| 220 bool is_hovered_for_test() {return button_hovered_; } | |
| 221 | |
| 222 private: | |
| 223 // Change the hover/active state of the "button" when the status changes. | |
| 224 void ShowActive(); | |
| 225 | |
| 226 // True if this is the active user. | |
| 227 bool is_active_user_; | |
| 228 | |
| 229 // True if button is hovered. | |
| 230 bool button_hovered_; | |
| 231 | |
| 232 // True if the border should be visible. | |
| 233 bool show_border_; | |
| 234 | |
| 235 DISALLOW_COPY_AND_ASSIGN(UserCard); | |
| 236 }; | |
| 237 | |
| 238 class UserViewMouseWatcherHost : public views::MouseWatcherHost { | |
| 239 public: | |
| 240 explicit UserViewMouseWatcherHost(const gfx::Rect& screen_area) | |
| 241 : screen_area_(screen_area) {} | |
| 242 virtual ~UserViewMouseWatcherHost() {} | |
| 243 | |
| 244 // Implementation of MouseWatcherHost. | |
| 245 virtual bool Contains(const gfx::Point& screen_point, | |
| 246 views::MouseWatcherHost::MouseEventType type) OVERRIDE { | |
| 247 return screen_area_.Contains(screen_point); | |
| 248 } | |
| 249 | |
| 250 private: | |
| 251 gfx::Rect screen_area_; | |
| 252 | |
| 253 DISALLOW_COPY_AND_ASSIGN(UserViewMouseWatcherHost); | |
| 254 }; | |
| 255 | |
| 256 // The view of a user item. | |
| 257 class UserView : public views::View, | |
| 258 public views::ButtonListener, | |
| 259 public views::MouseWatcherListener { | |
| 260 public: | |
| 261 UserView(SystemTrayItem* owner, | |
| 262 ash::user::LoginStatus login, | |
| 263 MultiProfileIndex index); | |
| 264 virtual ~UserView(); | |
| 265 | |
| 266 // Overridden from MouseWatcherListener: | |
| 267 virtual void MouseMovedOutOfHost() OVERRIDE; | |
| 268 | |
| 269 TrayUser::TestState GetStateForTest() const; | |
| 270 gfx::Rect GetBoundsInScreenOfUserButtonForTest(); | |
| 271 | |
| 272 private: | |
| 273 // Overridden from views::View. | |
| 274 virtual gfx::Size GetPreferredSize() OVERRIDE; | |
| 275 virtual int GetHeightForWidth(int width) OVERRIDE; | |
| 276 virtual void Layout() OVERRIDE; | |
| 277 | |
| 278 // Overridden from views::ButtonListener. | |
| 279 virtual void ButtonPressed(views::Button* sender, | |
| 280 const ui::Event& event) OVERRIDE; | |
| 281 | |
| 282 void AddLogoutButton(user::LoginStatus login); | |
| 283 void AddUserCard(SystemTrayItem* owner, user::LoginStatus login); | |
| 284 | |
| 285 // Create a user icon representation for the user card. | |
| 286 views::View* CreateIconForUserCard(user::LoginStatus login); | |
| 287 | |
| 288 // Create the additional user card content for the retail logged in mode. | |
| 289 void AddLoggedInRetailModeUserCardContent(); | |
| 290 | |
| 291 // Create the additional user card content for the public mode. | |
| 292 void AddLoggedInPublicModeUserCardContent(SystemTrayItem* owner); | |
| 293 | |
| 294 // Create the menu option to add another user. If |disabled| is set the user | |
| 295 // cannot actively click on the item. | |
| 296 void ToggleAddUserMenuOption(); | |
| 297 | |
| 298 // Returns true when multi profile is supported. | |
| 299 bool SupportsMultiProfile(); | |
| 300 | |
| 301 MultiProfileIndex multiprofile_index_; | |
| 302 // The view of the user card. | |
| 303 views::View* user_card_view_; | |
| 304 | |
| 305 // This is the owner system tray item of this view. | |
| 306 SystemTrayItem* owner_; | |
| 307 | |
| 308 // True if |user_card_view_| is a |UserView| - otherwise it is only a | |
| 309 // |views::View|. | |
| 310 bool is_user_card_; | |
| 311 views::View* logout_button_; | |
| 312 scoped_ptr<PopupMessage> popup_message_; | |
| 313 scoped_ptr<views::Widget> add_menu_option_; | |
| 314 | |
| 315 // True when the add user panel is visible but not activatable. | |
| 316 bool add_user_visible_but_disabled_; | |
| 317 | |
| 318 // The mouse watcher which takes care of out of window hover events. | |
| 319 scoped_ptr<views::MouseWatcher> mouse_watcher_; | |
| 320 | |
| 321 DISALLOW_COPY_AND_ASSIGN(UserView); | |
| 322 }; | |
| 323 | |
| 324 // The menu item view which gets shown when the user clicks in multi profile | |
| 325 // mode onto the user item. | |
| 326 class AddUserView : public views::CustomButton, | |
| 327 public views::ButtonListener { | |
| 328 public: | |
| 329 // The |owner| is the view for which this view gets created. The |listener| | |
| 330 // will get notified when this item gets clicked. | |
| 331 AddUserView(UserCard* owner, views::ButtonListener* listener); | |
| 332 virtual ~AddUserView(); | |
| 333 | |
| 334 // Get the anchor view for a message. | |
| 335 views::View* anchor() { return anchor_; } | |
| 336 | |
| 337 // Overridden from views::ButtonListener. | |
| 338 virtual void ButtonPressed(views::Button* sender, | |
| 339 const ui::Event& event) OVERRIDE; | |
| 340 | |
| 341 private: | |
| 342 // Overridden from views::View. | |
| 343 virtual gfx::Size GetPreferredSize() OVERRIDE; | |
| 344 virtual int GetHeightForWidth(int width) OVERRIDE; | |
| 345 virtual void Layout() OVERRIDE; | |
| 346 | |
| 347 // Create the additional client content for this item. | |
| 348 void AddContent(); | |
| 349 | |
| 350 // This is the content we create and show. | |
| 351 views::View* add_user_; | |
| 352 | |
| 353 // This listener will get informed when someone clicks on this button. | |
| 354 views::ButtonListener* listener_; | |
| 355 | |
| 356 // This is the owner view of this item. | |
| 357 UserCard* owner_; | |
| 358 | |
| 359 // The anchor view for targetted bubble messages. | |
| 360 views::View* anchor_; | |
| 361 | |
| 362 DISALLOW_COPY_AND_ASSIGN(AddUserView); | |
| 363 }; | |
| 364 | |
| 365 RoundedImageView::RoundedImageView(int corner_radius, bool active_user) | |
| 366 : active_user_(active_user) { | |
| 367 for (int i = 0; i < 4; ++i) | |
| 368 corner_radius_[i] = corner_radius; | |
| 369 } | |
| 370 | |
| 371 RoundedImageView::~RoundedImageView() {} | |
| 372 | |
| 373 void RoundedImageView::SetImage(const gfx::ImageSkia& img, | |
| 374 const gfx::Size& size) { | |
| 375 image_ = img; | |
| 376 image_size_ = size; | |
| 377 | |
| 378 // Try to get the best image quality for the avatar. | |
| 379 resized_ = gfx::ImageSkiaOperations::CreateResizedImage(image_, | |
| 380 skia::ImageOperations::RESIZE_BEST, size); | |
| 381 if (GetWidget() && visible()) { | |
| 382 PreferredSizeChanged(); | |
| 383 SchedulePaint(); | |
| 384 } | |
| 385 } | |
| 386 | |
| 387 void RoundedImageView::SetCornerRadii(int top_left, | |
| 388 int top_right, | |
| 389 int bottom_right, | |
| 390 int bottom_left) { | |
| 391 corner_radius_[0] = top_left; | |
| 392 corner_radius_[1] = top_right; | |
| 393 corner_radius_[2] = bottom_right; | |
| 394 corner_radius_[3] = bottom_left; | |
| 395 } | |
| 396 | |
| 397 gfx::Size RoundedImageView::GetPreferredSize() { | |
| 398 return gfx::Size(image_size_.width() + GetInsets().width(), | |
| 399 image_size_.height() + GetInsets().height()); | |
| 400 } | |
| 401 | |
| 402 void RoundedImageView::OnPaint(gfx::Canvas* canvas) { | |
| 403 View::OnPaint(canvas); | |
| 404 gfx::Rect image_bounds(size()); | |
| 405 image_bounds.ClampToCenteredSize(GetPreferredSize()); | |
| 406 image_bounds.Inset(GetInsets()); | |
| 407 const SkScalar kRadius[8] = { | |
| 408 SkIntToScalar(corner_radius_[0]), | |
| 409 SkIntToScalar(corner_radius_[0]), | |
| 410 SkIntToScalar(corner_radius_[1]), | |
| 411 SkIntToScalar(corner_radius_[1]), | |
| 412 SkIntToScalar(corner_radius_[2]), | |
| 413 SkIntToScalar(corner_radius_[2]), | |
| 414 SkIntToScalar(corner_radius_[3]), | |
| 415 SkIntToScalar(corner_radius_[3]) | |
| 416 }; | |
| 417 SkPath path; | |
| 418 path.addRoundRect(gfx::RectToSkRect(image_bounds), kRadius); | |
| 419 SkPaint paint; | |
| 420 paint.setAntiAlias(true); | |
| 421 paint.setXfermodeMode(active_user_ ? SkXfermode::kSrcOver_Mode : | |
| 422 SkXfermode::kLuminosity_Mode); | |
| 423 canvas->DrawImageInPath(resized_, image_bounds.x(), image_bounds.y(), | |
| 424 path, paint); | |
| 425 } | |
| 426 | |
| 427 PublicAccountUserDetails::PublicAccountUserDetails(SystemTrayItem* owner, | |
| 428 int used_width) | |
| 429 : learn_more_(NULL) { | |
| 430 const int inner_padding = | |
| 431 kTrayPopupPaddingHorizontal - kTrayPopupPaddingBetweenItems; | |
| 432 const bool rtl = base::i18n::IsRTL(); | |
| 433 SetBorder(views::Border::CreateEmptyBorder(kUserDetailsVerticalPadding, | |
| 434 rtl ? 0 : inner_padding, | |
| 435 kUserDetailsVerticalPadding, | |
| 436 rtl ? inner_padding : 0)); | |
| 437 | |
| 438 // Retrieve the user's display name and wrap it with markers. | |
| 439 // Note that since this is a public account it always has to be the primary | |
| 440 // user. | |
| 441 base::string16 display_name = | |
| 442 Shell::GetInstance()->session_state_delegate()->GetUserDisplayName(0); | |
| 443 base::RemoveChars(display_name, kDisplayNameMark, &display_name); | |
| 444 display_name = kDisplayNameMark[0] + display_name + kDisplayNameMark[0]; | |
| 445 // Retrieve the domain managing the device and wrap it with markers. | |
| 446 base::string16 domain = base::UTF8ToUTF16( | |
| 447 Shell::GetInstance()->system_tray_delegate()->GetEnterpriseDomain()); | |
| 448 base::RemoveChars(domain, kDisplayNameMark, &domain); | |
| 449 base::i18n::WrapStringWithLTRFormatting(&domain); | |
| 450 // Retrieve the label text, inserting the display name and domain. | |
| 451 text_ = l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_PUBLIC_LABEL, | |
| 452 display_name, domain); | |
| 453 | |
| 454 learn_more_ = new views::Link(l10n_util::GetStringUTF16(IDS_ASH_LEARN_MORE)); | |
| 455 learn_more_->SetUnderline(false); | |
| 456 learn_more_->set_listener(this); | |
| 457 AddChildView(learn_more_); | |
| 458 | |
| 459 CalculatePreferredSize(owner, used_width); | |
| 460 } | |
| 461 | |
| 462 PublicAccountUserDetails::~PublicAccountUserDetails() {} | |
| 463 | |
| 464 void PublicAccountUserDetails::Layout() { | |
| 465 lines_.clear(); | |
| 466 const gfx::Rect contents_area = GetContentsBounds(); | |
| 467 if (contents_area.IsEmpty()) | |
| 468 return; | |
| 469 | |
| 470 // Word-wrap the label text. | |
| 471 const gfx::FontList font_list; | |
| 472 std::vector<base::string16> lines; | |
| 473 gfx::ElideRectangleText(text_, font_list, contents_area.width(), | |
| 474 contents_area.height(), gfx::ELIDE_LONG_WORDS, | |
| 475 &lines); | |
| 476 // Loop through the lines, creating a renderer for each. | |
| 477 gfx::Point position = contents_area.origin(); | |
| 478 gfx::Range display_name(gfx::Range::InvalidRange()); | |
| 479 for (std::vector<base::string16>::const_iterator it = lines.begin(); | |
| 480 it != lines.end(); ++it) { | |
| 481 gfx::RenderText* line = gfx::RenderText::CreateInstance(); | |
| 482 line->SetDirectionalityMode(gfx::DIRECTIONALITY_FROM_UI); | |
| 483 line->SetText(*it); | |
| 484 const gfx::Size size(contents_area.width(), line->GetStringSize().height()); | |
| 485 line->SetDisplayRect(gfx::Rect(position, size)); | |
| 486 position.set_y(position.y() + size.height()); | |
| 487 | |
| 488 // Set the default text color for the line. | |
| 489 line->SetColor(kPublicAccountUserCardTextColor); | |
| 490 | |
| 491 // If a range of the line contains the user's display name, apply a custom | |
| 492 // text color to it. | |
| 493 if (display_name.is_empty()) | |
| 494 display_name.set_start(it->find(kDisplayNameMark)); | |
| 495 if (!display_name.is_empty()) { | |
| 496 display_name.set_end( | |
| 497 it->find(kDisplayNameMark, display_name.start() + 1)); | |
| 498 gfx::Range line_range(0, it->size()); | |
| 499 line->ApplyColor(kPublicAccountUserCardNameColor, | |
| 500 display_name.Intersect(line_range)); | |
| 501 // Update the range for the next line. | |
| 502 if (display_name.end() >= line_range.end()) | |
| 503 display_name.set_start(0); | |
| 504 else | |
| 505 display_name = gfx::Range::InvalidRange(); | |
| 506 } | |
| 507 | |
| 508 lines_.push_back(line); | |
| 509 } | |
| 510 | |
| 511 // Position the link after the label text, separated by a space. If it does | |
| 512 // not fit onto the last line of the text, wrap the link onto its own line. | |
| 513 const gfx::Size last_line_size = lines_.back()->GetStringSize(); | |
| 514 const int space_width = | |
| 515 gfx::GetStringWidth(base::ASCIIToUTF16(" "), font_list); | |
| 516 const gfx::Size link_size = learn_more_->GetPreferredSize(); | |
| 517 if (contents_area.width() - last_line_size.width() >= | |
| 518 space_width + link_size.width()) { | |
| 519 position.set_x(position.x() + last_line_size.width() + space_width); | |
| 520 position.set_y(position.y() - last_line_size.height()); | |
| 521 } | |
| 522 position.set_y(position.y() - learn_more_->GetInsets().top()); | |
| 523 gfx::Rect learn_more_bounds(position, link_size); | |
| 524 learn_more_bounds.Intersect(contents_area); | |
| 525 if (base::i18n::IsRTL()) { | |
| 526 const gfx::Insets insets = GetInsets(); | |
| 527 learn_more_bounds.Offset(insets.right() - insets.left(), 0); | |
| 528 } | |
| 529 learn_more_->SetBoundsRect(learn_more_bounds); | |
| 530 } | |
| 531 | |
| 532 gfx::Size PublicAccountUserDetails::GetPreferredSize() { | |
| 533 return preferred_size_; | |
| 534 } | |
| 535 | |
| 536 void PublicAccountUserDetails::OnPaint(gfx::Canvas* canvas) { | |
| 537 for (ScopedVector<gfx::RenderText>::const_iterator it = lines_.begin(); | |
| 538 it != lines_.end(); ++it) { | |
| 539 (*it)->Draw(canvas); | |
| 540 } | |
| 541 views::View::OnPaint(canvas); | |
| 542 } | |
| 543 | |
| 544 void PublicAccountUserDetails::LinkClicked(views::Link* source, | |
| 545 int event_flags) { | |
| 546 DCHECK_EQ(source, learn_more_); | |
| 547 Shell::GetInstance()->system_tray_delegate()->ShowPublicAccountInfo(); | |
| 548 } | |
| 549 | |
| 550 void PublicAccountUserDetails::CalculatePreferredSize(SystemTrayItem* owner, | |
| 551 int used_width) { | |
| 552 const gfx::FontList font_list; | |
| 553 const gfx::Size link_size = learn_more_->GetPreferredSize(); | |
| 554 const int space_width = | |
| 555 gfx::GetStringWidth(base::ASCIIToUTF16(" "), font_list); | |
| 556 const gfx::Insets insets = GetInsets(); | |
| 557 views::TrayBubbleView* bubble_view = | |
| 558 owner->system_tray()->GetSystemBubble()->bubble_view(); | |
| 559 int min_width = std::max( | |
| 560 link_size.width(), | |
| 561 bubble_view->GetPreferredSize().width() - (used_width + insets.width())); | |
| 562 int max_width = std::min( | |
| 563 gfx::GetStringWidth(text_, font_list) + space_width + link_size.width(), | |
| 564 bubble_view->GetMaximumSize().width() - (used_width + insets.width())); | |
| 565 // Do a binary search for the minimum width that ensures no more than three | |
| 566 // lines are needed. The lower bound is the minimum of the current bubble | |
| 567 // width and the width of the link (as no wrapping is permitted inside the | |
| 568 // link). The upper bound is the maximum of the largest allowed bubble width | |
| 569 // and the sum of the label text and link widths when put on a single line. | |
| 570 std::vector<base::string16> lines; | |
| 571 while (min_width < max_width) { | |
| 572 lines.clear(); | |
| 573 const int width = (min_width + max_width) / 2; | |
| 574 const bool too_narrow = | |
| 575 gfx::ElideRectangleText(text_, font_list, width, INT_MAX, | |
| 576 gfx::TRUNCATE_LONG_WORDS, &lines) != 0; | |
| 577 int line_count = lines.size(); | |
| 578 if (!too_narrow && line_count == 3 && | |
| 579 width - gfx::GetStringWidth(lines.back(), font_list) <= | |
| 580 space_width + link_size.width()) | |
| 581 ++line_count; | |
| 582 if (too_narrow || line_count > 3) | |
| 583 min_width = width + 1; | |
| 584 else | |
| 585 max_width = width; | |
| 586 } | |
| 587 | |
| 588 // Calculate the corresponding height and set the preferred size. | |
| 589 lines.clear(); | |
| 590 gfx::ElideRectangleText( | |
| 591 text_, font_list, min_width, INT_MAX, gfx::TRUNCATE_LONG_WORDS, &lines); | |
| 592 int line_count = lines.size(); | |
| 593 if (min_width - gfx::GetStringWidth(lines.back(), font_list) <= | |
| 594 space_width + link_size.width()) { | |
| 595 ++line_count; | |
| 596 } | |
| 597 const int line_height = font_list.GetHeight(); | |
| 598 const int link_extra_height = std::max( | |
| 599 link_size.height() - learn_more_->GetInsets().top() - line_height, 0); | |
| 600 preferred_size_ = gfx::Size( | |
| 601 min_width + insets.width(), | |
| 602 line_count * line_height + link_extra_height + insets.height()); | |
| 603 | |
| 604 bubble_view->SetWidth(preferred_size_.width() + used_width); | |
| 605 } | |
| 606 | |
| 607 UserCard::UserCard(views::ButtonListener* listener, bool active_user) | |
| 608 : CustomButton(listener), | |
| 609 is_active_user_(active_user), | |
| 610 button_hovered_(false), | |
| 611 show_border_(false) { | |
| 612 if (is_active_user_) { | |
| 613 set_background( | |
| 614 views::Background::CreateSolidBackground(kBackgroundColor)); | |
| 615 ShowActive(); | |
| 616 } | |
| 617 } | |
| 618 | |
| 619 UserCard::~UserCard() {} | |
| 620 | |
| 621 void UserCard::ForceBorderVisible(bool show) { | |
| 622 show_border_ = show; | |
| 623 ShowActive(); | |
| 624 } | |
| 625 | |
| 626 void UserCard::OnMouseEntered(const ui::MouseEvent& event) { | |
| 627 if (is_active_user_) { | |
| 628 button_hovered_ = true; | |
| 629 background()->SetNativeControlColor(kHoverBackgroundColor); | |
| 630 ShowActive(); | |
| 631 } | |
| 632 } | |
| 633 | |
| 634 void UserCard::OnMouseExited(const ui::MouseEvent& event) { | |
| 635 if (is_active_user_) { | |
| 636 button_hovered_ = false; | |
| 637 background()->SetNativeControlColor(kBackgroundColor); | |
| 638 ShowActive(); | |
| 639 } | |
| 640 } | |
| 641 | |
| 642 void UserCard::ShowActive() { | |
| 643 int width = button_hovered_ || show_border_ ? 1 : 0; | |
| 644 SetBorder(views::Border::CreateSolidSidedBorder( | |
| 645 width, width, width, 1, kBorderColor)); | |
| 646 SchedulePaint(); | |
| 647 } | |
| 648 | |
| 649 UserView::UserView(SystemTrayItem* owner, | |
| 650 user::LoginStatus login, | |
| 651 MultiProfileIndex index) | |
| 652 : multiprofile_index_(index), | |
| 653 user_card_view_(NULL), | |
| 654 owner_(owner), | |
| 655 is_user_card_(false), | |
| 656 logout_button_(NULL), | |
| 657 add_user_visible_but_disabled_(false) { | |
| 658 CHECK_NE(user::LOGGED_IN_NONE, login); | |
| 659 if (!index) { | |
| 660 // Only the logged in user will have a background. All other users will have | |
| 661 // to allow the TrayPopupContainer highlighting the menu line. | |
| 662 set_background(views::Background::CreateSolidBackground( | |
| 663 login == user::LOGGED_IN_PUBLIC ? kPublicAccountBackgroundColor : | |
| 664 kBackgroundColor)); | |
| 665 } | |
| 666 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, | |
| 667 kTrayPopupPaddingBetweenItems)); | |
| 668 // The logout button must be added before the user card so that the user card | |
| 669 // can correctly calculate the remaining available width. | |
| 670 // Note that only the current multiprofile user gets a button. | |
| 671 if (!multiprofile_index_) | |
| 672 AddLogoutButton(login); | |
| 673 AddUserCard(owner, login); | |
| 674 } | |
| 675 | |
| 676 UserView::~UserView() {} | |
| 677 | |
| 678 void UserView::MouseMovedOutOfHost() { | |
| 679 popup_message_.reset(); | |
| 680 mouse_watcher_.reset(); | |
| 681 add_menu_option_.reset(); | |
| 682 } | |
| 683 | |
| 684 TrayUser::TestState UserView::GetStateForTest() const { | |
| 685 if (add_menu_option_.get()) { | |
| 686 return add_user_visible_but_disabled_ ? TrayUser::ACTIVE_BUT_DISABLED : | |
| 687 TrayUser::ACTIVE; | |
| 688 } | |
| 689 | |
| 690 if (!is_user_card_) | |
| 691 return TrayUser::SHOWN; | |
| 692 | |
| 693 return static_cast<UserCard*>(user_card_view_)->is_hovered_for_test() ? | |
| 694 TrayUser::HOVERED : TrayUser::SHOWN; | |
| 695 } | |
| 696 | |
| 697 gfx::Rect UserView::GetBoundsInScreenOfUserButtonForTest() { | |
| 698 DCHECK(user_card_view_); | |
| 699 return user_card_view_->GetBoundsInScreen(); | |
| 700 } | |
| 701 | |
| 702 gfx::Size UserView::GetPreferredSize() { | |
| 703 gfx::Size size = views::View::GetPreferredSize(); | |
| 704 // Only the active user panel will be forced to a certain height. | |
| 705 if (!multiprofile_index_) { | |
| 706 size.set_height(std::max(size.height(), | |
| 707 kTrayPopupItemHeight + GetInsets().height())); | |
| 708 } | |
| 709 return size; | |
| 710 } | |
| 711 | |
| 712 int UserView::GetHeightForWidth(int width) { | |
| 713 return GetPreferredSize().height(); | |
| 714 } | |
| 715 | |
| 716 void UserView::Layout() { | |
| 717 gfx::Rect contents_area(GetContentsBounds()); | |
| 718 if (user_card_view_ && logout_button_) { | |
| 719 // Give the logout button the space it requests. | |
| 720 gfx::Rect logout_area = contents_area; | |
| 721 logout_area.ClampToCenteredSize(logout_button_->GetPreferredSize()); | |
| 722 logout_area.set_x(contents_area.right() - logout_area.width()); | |
| 723 | |
| 724 // Give the remaining space to the user card. | |
| 725 gfx::Rect user_card_area = contents_area; | |
| 726 int remaining_width = contents_area.width() - logout_area.width(); | |
| 727 if (SupportsMultiProfile()) { | |
| 728 // In multiprofile case |user_card_view_| and |logout_button_| have to | |
| 729 // have the same height. | |
| 730 int y = std::min(user_card_area.y(), logout_area.y()); | |
| 731 int height = std::max(user_card_area.height(), logout_area.height()); | |
| 732 logout_area.set_y(y); | |
| 733 logout_area.set_height(height); | |
| 734 user_card_area.set_y(y); | |
| 735 user_card_area.set_height(height); | |
| 736 | |
| 737 // In multiprofile mode we have also to increase the size of the card by | |
| 738 // the size of the border to make it overlap with the logout button. | |
| 739 user_card_area.set_width(std::max(0, remaining_width + 1)); | |
| 740 | |
| 741 // To make the logout button symmetrical with the user card we also make | |
| 742 // the button longer by the same size the hover area in front of the icon | |
| 743 // got inset. | |
| 744 logout_area.set_width(logout_area.width() + | |
| 745 kTrayUserTileHoverBorderInset); | |
| 746 } else { | |
| 747 // In all other modes we have to make sure that there is enough spacing | |
| 748 // between the two. | |
| 749 remaining_width -= kTrayPopupPaddingBetweenItems; | |
| 750 } | |
| 751 user_card_area.set_width(remaining_width); | |
| 752 user_card_view_->SetBoundsRect(user_card_area); | |
| 753 logout_button_->SetBoundsRect(logout_area); | |
| 754 } else if (user_card_view_) { | |
| 755 user_card_view_->SetBoundsRect(contents_area); | |
| 756 } else if (logout_button_) { | |
| 757 logout_button_->SetBoundsRect(contents_area); | |
| 758 } | |
| 759 } | |
| 760 | |
| 761 void UserView::ButtonPressed(views::Button* sender, const ui::Event& event) { | |
| 762 if (sender == logout_button_) { | |
| 763 Shell::GetInstance()->metrics()->RecordUserMetricsAction( | |
| 764 ash::UMA_STATUS_AREA_SIGN_OUT); | |
| 765 Shell::GetInstance()->system_tray_delegate()->SignOut(); | |
| 766 } else if (sender == user_card_view_ && SupportsMultiProfile()) { | |
| 767 if (!multiprofile_index_) { | |
| 768 ToggleAddUserMenuOption(); | |
| 769 } else { | |
| 770 SwitchUser(multiprofile_index_); | |
| 771 // Since the user list is about to change the system menu should get | |
| 772 // closed. | |
| 773 owner_->system_tray()->CloseSystemBubble(); | |
| 774 } | |
| 775 } else if (add_menu_option_.get() && | |
| 776 sender == add_menu_option_->GetContentsView()) { | |
| 777 // Let the user add another account to the session. | |
| 778 MultiProfileUMA::RecordSigninUser(MultiProfileUMA::SIGNIN_USER_BY_TRAY); | |
| 779 Shell::GetInstance()->system_tray_delegate()->ShowUserLogin(); | |
| 780 owner_->system_tray()->CloseSystemBubble(); | |
| 781 } else { | |
| 782 NOTREACHED(); | |
| 783 } | |
| 784 } | |
| 785 | |
| 786 void UserView::AddLogoutButton(user::LoginStatus login) { | |
| 787 const base::string16 title = user::GetLocalizedSignOutStringForStatus(login, | |
| 788 true); | |
| 789 TrayPopupLabelButton* logout_button = new TrayPopupLabelButton(this, title); | |
| 790 logout_button->SetAccessibleName(title); | |
| 791 logout_button_ = logout_button; | |
| 792 // In public account mode, the logout button border has a custom color. | |
| 793 if (login == user::LOGGED_IN_PUBLIC) { | |
| 794 scoped_ptr<TrayPopupLabelButtonBorder> border( | |
| 795 new TrayPopupLabelButtonBorder()); | |
| 796 border->SetPainter(false, views::Button::STATE_NORMAL, | |
| 797 views::Painter::CreateImageGridPainter( | |
| 798 kPublicAccountLogoutButtonBorderImagesNormal)); | |
| 799 border->SetPainter(false, views::Button::STATE_HOVERED, | |
| 800 views::Painter::CreateImageGridPainter( | |
| 801 kPublicAccountLogoutButtonBorderImagesHovered)); | |
| 802 border->SetPainter(false, views::Button::STATE_PRESSED, | |
| 803 views::Painter::CreateImageGridPainter( | |
| 804 kPublicAccountLogoutButtonBorderImagesHovered)); | |
| 805 logout_button_->SetBorder(border.PassAs<views::Border>()); | |
| 806 } | |
| 807 AddChildView(logout_button_); | |
| 808 } | |
| 809 | |
| 810 void UserView::AddUserCard(SystemTrayItem* owner, user::LoginStatus login) { | |
| 811 // Add padding around the panel. | |
| 812 SetBorder(views::Border::CreateEmptyBorder(kUserCardVerticalPadding, | |
| 813 kTrayPopupPaddingHorizontal, | |
| 814 kUserCardVerticalPadding, | |
| 815 kTrayPopupPaddingHorizontal)); | |
| 816 | |
| 817 if (SupportsMultiProfile() && login != user::LOGGED_IN_RETAIL_MODE) { | |
| 818 user_card_view_ = new UserCard(this, multiprofile_index_ == 0); | |
| 819 is_user_card_ = true; | |
| 820 } else { | |
| 821 user_card_view_ = new views::View(); | |
| 822 is_user_card_ = false; | |
| 823 } | |
| 824 | |
| 825 user_card_view_->SetLayoutManager(new views::BoxLayout( | |
| 826 views::BoxLayout::kHorizontal, 0, 0 , kTrayPopupPaddingBetweenItems)); | |
| 827 AddChildViewAt(user_card_view_, 0); | |
| 828 | |
| 829 if (login == user::LOGGED_IN_RETAIL_MODE) { | |
| 830 AddLoggedInRetailModeUserCardContent(); | |
| 831 return; | |
| 832 } | |
| 833 | |
| 834 // The entire user card should trigger hover (the inner items get disabled). | |
| 835 user_card_view_->SetEnabled(true); | |
| 836 user_card_view_->set_notify_enter_exit_on_child(true); | |
| 837 | |
| 838 if (login == user::LOGGED_IN_PUBLIC) { | |
| 839 AddLoggedInPublicModeUserCardContent(owner); | |
| 840 return; | |
| 841 } | |
| 842 | |
| 843 views::View* icon = CreateIconForUserCard(login); | |
| 844 user_card_view_->AddChildView(icon); | |
| 845 | |
| 846 // To allow the border to start before the icon, reduce the size before and | |
| 847 // add an inset to the icon to get the spacing. | |
| 848 if (multiprofile_index_ == 0 && SupportsMultiProfile()) { | |
| 849 icon->SetBorder(views::Border::CreateEmptyBorder( | |
| 850 0, kTrayUserTileHoverBorderInset, 0, 0)); | |
| 851 SetBorder(views::Border::CreateEmptyBorder( | |
| 852 kUserCardVerticalPadding, | |
| 853 kTrayPopupPaddingHorizontal - kTrayUserTileHoverBorderInset, | |
| 854 kUserCardVerticalPadding, | |
| 855 kTrayPopupPaddingHorizontal)); | |
| 856 } | |
| 857 SessionStateDelegate* delegate = | |
| 858 Shell::GetInstance()->session_state_delegate(); | |
| 859 views::Label* username = NULL; | |
| 860 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
| 861 if (!multiprofile_index_) { | |
| 862 base::string16 user_name_string = | |
| 863 login == user::LOGGED_IN_GUEST ? | |
| 864 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_GUEST_LABEL) : | |
| 865 delegate->GetUserDisplayName(multiprofile_index_); | |
| 866 if (!user_name_string.empty()) { | |
| 867 username = new views::Label(user_name_string); | |
| 868 username->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
| 869 } | |
| 870 } | |
| 871 | |
| 872 views::Label* additional = NULL; | |
| 873 if (login != user::LOGGED_IN_GUEST) { | |
| 874 base::string16 user_email_string = | |
| 875 login == user::LOGGED_IN_LOCALLY_MANAGED ? | |
| 876 bundle.GetLocalizedString( | |
| 877 IDS_ASH_STATUS_TRAY_LOCALLY_MANAGED_LABEL) : | |
| 878 base::UTF8ToUTF16(delegate->GetUserEmail(multiprofile_index_)); | |
| 879 if (!user_email_string.empty()) { | |
| 880 additional = new views::Label(user_email_string); | |
| 881 additional->SetFontList( | |
| 882 bundle.GetFontList(ui::ResourceBundle::SmallFont)); | |
| 883 additional->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
| 884 } | |
| 885 } | |
| 886 | |
| 887 // Adjust text properties dependent on if it is an active or inactive user. | |
| 888 if (multiprofile_index_) { | |
| 889 // Fade the text of non active users to 50%. | |
| 890 SkColor text_color = additional->enabled_color(); | |
| 891 text_color = SkColorSetA(text_color, SkColorGetA(text_color) / 2); | |
| 892 if (additional) | |
| 893 additional->SetDisabledColor(text_color); | |
| 894 if (username) | |
| 895 username->SetDisabledColor(text_color); | |
| 896 } | |
| 897 | |
| 898 if (additional && username) { | |
| 899 views::View* details = new views::View; | |
| 900 details->SetLayoutManager(new views::BoxLayout( | |
| 901 views::BoxLayout::kVertical, 0, kUserDetailsVerticalPadding, 0)); | |
| 902 details->AddChildView(username); | |
| 903 details->AddChildView(additional); | |
| 904 user_card_view_->AddChildView(details); | |
| 905 } else { | |
| 906 if (username) | |
| 907 user_card_view_->AddChildView(username); | |
| 908 if (additional) | |
| 909 user_card_view_->AddChildView(additional); | |
| 910 } | |
| 911 } | |
| 912 | |
| 913 views::View* UserView::CreateIconForUserCard(user::LoginStatus login) { | |
| 914 RoundedImageView* icon = new RoundedImageView(kProfileRoundedCornerRadius, | |
| 915 multiprofile_index_ == 0); | |
| 916 icon->SetEnabled(false); | |
| 917 if (login == user::LOGGED_IN_GUEST) { | |
| 918 icon->SetImage(*ui::ResourceBundle::GetSharedInstance(). | |
| 919 GetImageNamed(IDR_AURA_UBER_TRAY_GUEST_ICON).ToImageSkia(), | |
| 920 gfx::Size(kUserIconSize, kUserIconSize)); | |
| 921 } else { | |
| 922 SessionStateDelegate* delegate = | |
| 923 Shell::GetInstance()->session_state_delegate(); | |
| 924 content::BrowserContext* context = delegate->GetBrowserContextByIndex( | |
| 925 multiprofile_index_); | |
| 926 icon->SetImage(delegate->GetUserImage(context), | |
| 927 gfx::Size(kUserIconSize, kUserIconSize)); | |
| 928 } | |
| 929 return icon; | |
| 930 } | |
| 931 | |
| 932 void UserView::AddLoggedInRetailModeUserCardContent() { | |
| 933 views::Label* details = new views::Label; | |
| 934 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
| 935 details->SetText( | |
| 936 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_KIOSK_LABEL)); | |
| 937 details->SetBorder(views::Border::CreateEmptyBorder(0, 4, 0, 1)); | |
| 938 details->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
| 939 user_card_view_->AddChildView(details); | |
| 940 } | |
| 941 | |
| 942 void UserView::AddLoggedInPublicModeUserCardContent(SystemTrayItem* owner) { | |
| 943 user_card_view_->AddChildView(CreateIconForUserCard(user::LOGGED_IN_PUBLIC)); | |
| 944 user_card_view_->AddChildView(new PublicAccountUserDetails( | |
| 945 owner, GetPreferredSize().width() + kTrayPopupPaddingBetweenItems)); | |
| 946 } | |
| 947 | |
| 948 void UserView::ToggleAddUserMenuOption() { | |
| 949 if (add_menu_option_.get()) { | |
| 950 popup_message_.reset(); | |
| 951 mouse_watcher_.reset(); | |
| 952 add_menu_option_.reset(); | |
| 953 return; | |
| 954 } | |
| 955 | |
| 956 // Note: We do not need to install a global event handler to delete this | |
| 957 // item since it will destroyed automatically before the menu / user menu item | |
| 958 // gets destroyed.. | |
| 959 const SessionStateDelegate* session_state_delegate = | |
| 960 Shell::GetInstance()->session_state_delegate(); | |
| 961 add_user_visible_but_disabled_ = | |
| 962 session_state_delegate->NumberOfLoggedInUsers() >= | |
| 963 session_state_delegate->GetMaximumNumberOfLoggedInUsers(); | |
| 964 add_menu_option_.reset(new views::Widget); | |
| 965 views::Widget::InitParams params; | |
| 966 params.type = views::Widget::InitParams::TYPE_TOOLTIP; | |
| 967 params.keep_on_top = true; | |
| 968 params.context = this->GetWidget()->GetNativeWindow(); | |
| 969 params.accept_events = true; | |
| 970 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 971 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | |
| 972 add_menu_option_->Init(params); | |
| 973 add_menu_option_->SetOpacity(0xFF); | |
| 974 add_menu_option_->GetNativeWindow()->set_owned_by_parent(false); | |
| 975 SetShadowType(add_menu_option_->GetNativeView(), | |
| 976 wm::SHADOW_TYPE_NONE); | |
| 977 | |
| 978 // Position it below our user card. | |
| 979 gfx::Rect bounds = user_card_view_->GetBoundsInScreen(); | |
| 980 bounds.set_y(bounds.y() + bounds.height()); | |
| 981 add_menu_option_->SetBounds(bounds); | |
| 982 | |
| 983 // Show the content. | |
| 984 AddUserView* add_user_view = new AddUserView( | |
| 985 static_cast<UserCard*>(user_card_view_), this); | |
| 986 add_menu_option_->SetContentsView(add_user_view); | |
| 987 add_menu_option_->SetAlwaysOnTop(true); | |
| 988 add_menu_option_->Show(); | |
| 989 if (add_user_visible_but_disabled_) { | |
| 990 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
| 991 popup_message_.reset(new PopupMessage( | |
| 992 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAPTION_CANNOT_ADD_USER), | |
| 993 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER), | |
| 994 PopupMessage::ICON_WARNING, | |
| 995 add_user_view->anchor(), | |
| 996 views::BubbleBorder::TOP_LEFT, | |
| 997 gfx::Size(parent()->bounds().width() - kPopupMessageOffset, 0), | |
| 998 2 * kPopupMessageOffset)); | |
| 999 } | |
| 1000 // Find the screen area which encloses both elements and sets then a mouse | |
| 1001 // watcher which will close the "menu". | |
| 1002 gfx::Rect area = user_card_view_->GetBoundsInScreen(); | |
| 1003 area.set_height(2 * area.height()); | |
| 1004 mouse_watcher_.reset(new views::MouseWatcher( | |
| 1005 new UserViewMouseWatcherHost(area), | |
| 1006 this)); | |
| 1007 mouse_watcher_->Start(); | |
| 1008 } | |
| 1009 | |
| 1010 bool UserView::SupportsMultiProfile() { | |
| 1011 // We do not want to see any multi profile additions to a user view when the | |
| 1012 // log in screen is shown. | |
| 1013 return Shell::GetInstance()->delegate()->IsMultiProfilesEnabled() && | |
| 1014 !Shell::GetInstance()->session_state_delegate()->IsUserSessionBlocked(); | |
| 1015 } | |
| 1016 | |
| 1017 AddUserView::AddUserView(UserCard* owner, views::ButtonListener* listener) | |
| 1018 : CustomButton(listener), | |
| 1019 add_user_(NULL), | |
| 1020 listener_(listener), | |
| 1021 owner_(owner), | |
| 1022 anchor_(NULL) { | |
| 1023 AddContent(); | |
| 1024 owner_->ForceBorderVisible(true); | |
| 1025 } | |
| 1026 | |
| 1027 AddUserView::~AddUserView() { | |
| 1028 owner_->ForceBorderVisible(false); | |
| 1029 } | |
| 1030 | |
| 1031 gfx::Size AddUserView::GetPreferredSize() { | |
| 1032 return owner_->bounds().size(); | |
| 1033 } | |
| 1034 | |
| 1035 int AddUserView::GetHeightForWidth(int width) { | |
| 1036 return owner_->bounds().size().height(); | |
| 1037 } | |
| 1038 | |
| 1039 void AddUserView::Layout() { | |
| 1040 gfx::Rect contents_area(GetContentsBounds()); | |
| 1041 add_user_->SetBoundsRect(contents_area); | |
| 1042 } | |
| 1043 | |
| 1044 void AddUserView::ButtonPressed(views::Button* sender, const ui::Event& event) { | |
| 1045 if (add_user_ == sender) | |
| 1046 listener_->ButtonPressed(this, event); | |
| 1047 else | |
| 1048 NOTREACHED(); | |
| 1049 } | |
| 1050 | |
| 1051 void AddUserView::AddContent() { | |
| 1052 set_notify_enter_exit_on_child(true); | |
| 1053 | |
| 1054 const SessionStateDelegate* delegate = | |
| 1055 Shell::GetInstance()->session_state_delegate(); | |
| 1056 bool enable = delegate->NumberOfLoggedInUsers() < | |
| 1057 delegate->GetMaximumNumberOfLoggedInUsers(); | |
| 1058 | |
| 1059 SetLayoutManager(new views::FillLayout()); | |
| 1060 set_background(views::Background::CreateSolidBackground(kBackgroundColor)); | |
| 1061 | |
| 1062 // Add padding around the panel. | |
| 1063 SetBorder(views::Border::CreateSolidBorder(1, kBorderColor)); | |
| 1064 | |
| 1065 add_user_ = new UserCard(this, enable); | |
| 1066 add_user_->SetBorder(views::Border::CreateEmptyBorder( | |
| 1067 kUserCardVerticalPadding, | |
| 1068 kTrayPopupPaddingHorizontal - kTrayUserTileHoverBorderInset, | |
| 1069 kUserCardVerticalPadding, | |
| 1070 kTrayPopupPaddingHorizontal - kTrayUserTileHoverBorderInset)); | |
| 1071 | |
| 1072 add_user_->SetLayoutManager(new views::BoxLayout( | |
| 1073 views::BoxLayout::kHorizontal, 0, 0 , kTrayPopupPaddingBetweenItems)); | |
| 1074 AddChildViewAt(add_user_, 0); | |
| 1075 | |
| 1076 // Add the [+] icon which is also the anchor for messages. | |
| 1077 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
| 1078 RoundedImageView* icon = new RoundedImageView(kProfileRoundedCornerRadius, | |
| 1079 true); | |
| 1080 anchor_ = icon; | |
| 1081 icon->SetImage(*ui::ResourceBundle::GetSharedInstance(). | |
| 1082 GetImageNamed(IDR_AURA_UBER_TRAY_ADD_MULTIPROFILE_USER).ToImageSkia(), | |
| 1083 gfx::Size(kUserIconSize, kUserIconSize)); | |
| 1084 add_user_->AddChildView(icon); | |
| 1085 | |
| 1086 // Add the command text. | |
| 1087 views::Label* command_label = new views::Label( | |
| 1088 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); | |
| 1089 command_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
| 1090 add_user_->AddChildView(command_label); | |
| 1091 } | |
| 1092 | |
| 1093 } // namespace tray | |
| 1094 | 42 |
| 1095 TrayUser::TrayUser(SystemTray* system_tray, MultiProfileIndex index) | 43 TrayUser::TrayUser(SystemTray* system_tray, MultiProfileIndex index) |
| 1096 : SystemTrayItem(system_tray), | 44 : SystemTrayItem(system_tray), |
| 1097 multiprofile_index_(index), | 45 multiprofile_index_(index), |
| 1098 user_(NULL), | 46 user_(NULL), |
| 1099 layout_view_(NULL), | 47 layout_view_(NULL), |
| 1100 avatar_(NULL), | 48 avatar_(NULL), |
| 1101 label_(NULL) { | 49 label_(NULL) { |
| 1102 Shell::GetInstance()->system_tray_notifier()->AddUserObserver(this); | 50 Shell::GetInstance()->system_tray_notifier()->AddUserObserver(this); |
| 1103 } | 51 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1125 return user_->GetBoundsInScreenOfUserButtonForTest(); | 73 return user_->GetBoundsInScreenOfUserButtonForTest(); |
| 1126 } | 74 } |
| 1127 | 75 |
| 1128 void TrayUser::UpdateAfterLoginStatusChangeForTest(user::LoginStatus status) { | 76 void TrayUser::UpdateAfterLoginStatusChangeForTest(user::LoginStatus status) { |
| 1129 UpdateAfterLoginStatusChange(status); | 77 UpdateAfterLoginStatusChange(status); |
| 1130 } | 78 } |
| 1131 | 79 |
| 1132 views::View* TrayUser::CreateTrayView(user::LoginStatus status) { | 80 views::View* TrayUser::CreateTrayView(user::LoginStatus status) { |
| 1133 CHECK(layout_view_ == NULL); | 81 CHECK(layout_view_ == NULL); |
| 1134 | 82 |
| 1135 layout_view_ = new views::View(); | 83 layout_view_ = new views::View; |
| 1136 layout_view_->SetLayoutManager( | 84 layout_view_->SetLayoutManager( |
| 1137 new views::BoxLayout(views::BoxLayout::kHorizontal, | 85 new views::BoxLayout(views::BoxLayout::kHorizontal, |
| 1138 0, 0, kUserLabelToIconPadding)); | 86 0, 0, kUserLabelToIconPadding)); |
| 1139 UpdateAfterLoginStatusChange(status); | 87 UpdateAfterLoginStatusChange(status); |
| 1140 return layout_view_; | 88 return layout_view_; |
| 1141 } | 89 } |
| 1142 | 90 |
| 1143 views::View* TrayUser::CreateDefaultView(user::LoginStatus status) { | 91 views::View* TrayUser::CreateDefaultView(user::LoginStatus status) { |
| 1144 if (status == user::LOGGED_IN_NONE) | 92 if (status == user::LOGGED_IN_NONE) |
| 1145 return NULL; | 93 return NULL; |
| 1146 const SessionStateDelegate* session_state_delegate = | 94 const SessionStateDelegate* session_state_delegate = |
| 1147 Shell::GetInstance()->session_state_delegate(); | 95 Shell::GetInstance()->session_state_delegate(); |
| 1148 | 96 |
| 1149 // If the screen is locked show only the currently active user. | 97 // If the screen is locked show only the currently active user. |
| 1150 if (multiprofile_index_ && session_state_delegate->IsUserSessionBlocked()) | 98 if (multiprofile_index_ && session_state_delegate->IsUserSessionBlocked()) |
| 1151 return NULL; | 99 return NULL; |
| 1152 | 100 |
| 1153 CHECK(user_ == NULL); | 101 CHECK(user_ == NULL); |
| 1154 | 102 |
| 1155 int logged_in_users = session_state_delegate->NumberOfLoggedInUsers(); | 103 int logged_in_users = session_state_delegate->NumberOfLoggedInUsers(); |
| 1156 | 104 |
| 1157 // Do not show more UserView's then there are logged in users. | 105 // Do not show more UserView's then there are logged in users. |
| 1158 if (multiprofile_index_ >= logged_in_users) | 106 if (multiprofile_index_ >= logged_in_users) |
| 1159 return NULL; | 107 return NULL; |
| 1160 | 108 |
| 1161 user_ = new tray::UserView(this, status, multiprofile_index_); | 109 user_ = new tray::UserView(this, status, multiprofile_index_, false); |
| 1162 return user_; | 110 return user_; |
| 1163 } | 111 } |
| 1164 | 112 |
| 1165 views::View* TrayUser::CreateDetailedView(user::LoginStatus status) { | 113 views::View* TrayUser::CreateDetailedView(user::LoginStatus status) { |
| 1166 return NULL; | 114 return new tray::AccountsDetailedView(this, status); |
| 1167 } | 115 } |
| 1168 | 116 |
| 1169 void TrayUser::DestroyTrayView() { | 117 void TrayUser::DestroyTrayView() { |
| 1170 layout_view_ = NULL; | 118 layout_view_ = NULL; |
| 1171 avatar_ = NULL; | 119 avatar_ = NULL; |
| 1172 label_ = NULL; | 120 label_ = NULL; |
| 1173 } | 121 } |
| 1174 | 122 |
| 1175 void TrayUser::DestroyDefaultView() { | 123 void TrayUser::DestroyDefaultView() { |
| 1176 user_ = NULL; | 124 user_ = NULL; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1211 (need_label != (label_ != NULL))) { | 159 (need_label != (label_ != NULL))) { |
| 1212 layout_view_->RemoveAllChildViews(true); | 160 layout_view_->RemoveAllChildViews(true); |
| 1213 if (need_label) { | 161 if (need_label) { |
| 1214 label_ = new views::Label; | 162 label_ = new views::Label; |
| 1215 SetupLabelForTray(label_); | 163 SetupLabelForTray(label_); |
| 1216 layout_view_->AddChildView(label_); | 164 layout_view_->AddChildView(label_); |
| 1217 } else { | 165 } else { |
| 1218 label_ = NULL; | 166 label_ = NULL; |
| 1219 } | 167 } |
| 1220 if (need_avatar) { | 168 if (need_avatar) { |
| 1221 avatar_ = new tray::RoundedImageView(kProfileRoundedCornerRadius, true); | 169 avatar_ = new tray::RoundedImageView(kTrayAvatarCornerRadius, true); |
| 1222 layout_view_->AddChildView(avatar_); | 170 layout_view_->AddChildView(avatar_); |
| 1223 } else { | 171 } else { |
| 1224 avatar_ = NULL; | 172 avatar_ = NULL; |
| 1225 } | 173 } |
| 1226 } | 174 } |
| 1227 | 175 |
| 1228 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
| 1229 if (status == user::LOGGED_IN_LOCALLY_MANAGED) { | 176 if (status == user::LOGGED_IN_LOCALLY_MANAGED) { |
| 1230 label_->SetText( | 177 label_->SetText( |
| 1231 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOCALLY_MANAGED_LABEL)); | 178 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_LOCALLY_MANAGED_LABEL)); |
| 1232 } else if (status == user::LOGGED_IN_GUEST) { | 179 } else if (status == user::LOGGED_IN_GUEST) { |
| 1233 label_->SetText(bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_GUEST_LABEL)); | 180 label_->SetText(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_GUEST_LABEL)); |
| 1234 } | 181 } |
| 1235 | 182 |
| 1236 if (avatar_ && switches::UseAlternateShelfLayout()) { | 183 if (avatar_ && switches::UseAlternateShelfLayout()) { |
| 1237 avatar_->SetCornerRadii( | 184 avatar_->SetCornerRadii( |
| 1238 0, kUserIconLargeCornerRadius, kUserIconLargeCornerRadius, 0); | 185 0, kTrayAvatarLargeCornerRadius, kTrayAvatarLargeCornerRadius, 0); |
| 1239 avatar_->SetBorder(views::Border::NullBorder()); | 186 avatar_->SetBorder(views::Border::NullBorder()); |
| 1240 } | 187 } |
| 1241 UpdateAvatarImage(status); | 188 UpdateAvatarImage(status); |
| 1242 | 189 |
| 1243 // Update layout after setting label_ and avatar_ with new login status. | 190 // Update layout after setting label_ and avatar_ with new login status. |
| 1244 UpdateLayoutOfItem(); | 191 UpdateLayoutOfItem(); |
| 1245 } | 192 } |
| 1246 | 193 |
| 1247 void TrayUser::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { | 194 void TrayUser::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { |
| 1248 // Inactive users won't have a layout. | 195 // Inactive users won't have a layout. |
| 1249 if (!layout_view_) | 196 if (!layout_view_) |
| 1250 return; | 197 return; |
| 1251 if (alignment == SHELF_ALIGNMENT_BOTTOM || | 198 if (alignment == SHELF_ALIGNMENT_BOTTOM || |
| 1252 alignment == SHELF_ALIGNMENT_TOP) { | 199 alignment == SHELF_ALIGNMENT_TOP) { |
| 1253 if (avatar_) { | 200 if (avatar_) { |
| 1254 if (switches::UseAlternateShelfLayout()) { | 201 if (switches::UseAlternateShelfLayout()) { |
| 1255 avatar_->SetBorder(views::Border::NullBorder()); | 202 avatar_->SetBorder(views::Border::NullBorder()); |
| 1256 avatar_->SetCornerRadii( | 203 avatar_->SetCornerRadii( |
| 1257 0, kUserIconLargeCornerRadius, kUserIconLargeCornerRadius, 0); | 204 0, kTrayAvatarLargeCornerRadius, kTrayAvatarLargeCornerRadius, 0); |
| 1258 } else { | 205 } else { |
| 1259 avatar_->SetBorder(views::Border::CreateEmptyBorder( | 206 avatar_->SetBorder(views::Border::CreateEmptyBorder( |
| 1260 0, | 207 0, |
| 1261 kTrayImageItemHorizontalPaddingBottomAlignment + 2, | 208 kTrayImageItemHorizontalPaddingBottomAlignment + 2, |
| 1262 0, | 209 0, |
| 1263 kTrayImageItemHorizontalPaddingBottomAlignment)); | 210 kTrayImageItemHorizontalPaddingBottomAlignment)); |
| 1264 } | 211 } |
| 1265 } | 212 } |
| 1266 if (label_) { | 213 if (label_) { |
| 1267 // If label_ hasn't figured out its size yet, do that first. | 214 // If label_ hasn't figured out its size yet, do that first. |
| 1268 if (label_->GetContentsBounds().height() == 0) | 215 if (label_->GetContentsBounds().height() == 0) |
| 1269 label_->SizeToPreferredSize(); | 216 label_->SizeToPreferredSize(); |
| 1270 int height = label_->GetContentsBounds().height(); | 217 int height = label_->GetContentsBounds().height(); |
| 1271 int vertical_pad = (kTrayItemSize - height) / 2; | 218 int vertical_pad = (kTrayItemSize - height) / 2; |
| 1272 int remainder = height % 2; | 219 int remainder = height % 2; |
| 1273 label_->SetBorder(views::Border::CreateEmptyBorder( | 220 label_->SetBorder(views::Border::CreateEmptyBorder( |
| 1274 vertical_pad + remainder, | 221 vertical_pad + remainder, |
| 1275 kTrayLabelItemHorizontalPaddingBottomAlignment, | 222 kTrayLabelItemHorizontalPaddingBottomAlignment, |
| 1276 vertical_pad, | 223 vertical_pad, |
| 1277 kTrayLabelItemHorizontalPaddingBottomAlignment)); | 224 kTrayLabelItemHorizontalPaddingBottomAlignment)); |
| 1278 } | 225 } |
| 1279 layout_view_->SetLayoutManager( | 226 layout_view_->SetLayoutManager( |
| 1280 new views::BoxLayout(views::BoxLayout::kHorizontal, | 227 new views::BoxLayout(views::BoxLayout::kHorizontal, |
| 1281 0, 0, kUserLabelToIconPadding)); | 228 0, 0, kUserLabelToIconPadding)); |
| 1282 } else { | 229 } else { |
| 1283 if (avatar_) { | 230 if (avatar_) { |
| 1284 if (switches::UseAlternateShelfLayout()) { | 231 if (switches::UseAlternateShelfLayout()) { |
| 1285 avatar_->SetBorder(views::Border::NullBorder()); | 232 avatar_->SetBorder(views::Border::NullBorder()); |
| 1286 avatar_->SetCornerRadii( | 233 avatar_->SetCornerRadii( |
| 1287 0, 0, kUserIconLargeCornerRadius, kUserIconLargeCornerRadius); | 234 0, 0, kTrayAvatarLargeCornerRadius, kTrayAvatarLargeCornerRadius); |
| 1288 } else { | 235 } else { |
| 1289 SetTrayImageItemBorder(avatar_, alignment); | 236 SetTrayImageItemBorder(avatar_, alignment); |
| 1290 } | 237 } |
| 1291 } | 238 } |
| 1292 if (label_) { | 239 if (label_) { |
| 1293 label_->SetBorder(views::Border::CreateEmptyBorder( | 240 label_->SetBorder(views::Border::CreateEmptyBorder( |
| 1294 kTrayLabelItemVerticalPaddingVerticalAlignment, | 241 kTrayLabelItemVerticalPaddingVerticalAlignment, |
| 1295 kTrayLabelItemHorizontalPaddingBottomAlignment, | 242 kTrayLabelItemHorizontalPaddingBottomAlignment, |
| 1296 kTrayLabelItemVerticalPaddingVerticalAlignment, | 243 kTrayLabelItemVerticalPaddingVerticalAlignment, |
| 1297 kTrayLabelItemHorizontalPaddingBottomAlignment)); | 244 kTrayLabelItemHorizontalPaddingBottomAlignment)); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1322 Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus()); | 269 Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus()); |
| 1323 } | 270 } |
| 1324 | 271 |
| 1325 void TrayUser::UpdateAvatarImage(user::LoginStatus status) { | 272 void TrayUser::UpdateAvatarImage(user::LoginStatus status) { |
| 1326 SessionStateDelegate* session_state_delegate = | 273 SessionStateDelegate* session_state_delegate = |
| 1327 Shell::GetInstance()->session_state_delegate(); | 274 Shell::GetInstance()->session_state_delegate(); |
| 1328 if (!avatar_ || | 275 if (!avatar_ || |
| 1329 GetTrayIndex() >= session_state_delegate->NumberOfLoggedInUsers()) | 276 GetTrayIndex() >= session_state_delegate->NumberOfLoggedInUsers()) |
| 1330 return; | 277 return; |
| 1331 | 278 |
| 1332 int icon_size = switches::UseAlternateShelfLayout() ? | 279 int icon_size = switches::UseAlternateShelfLayout() ? kTrayAvatarLargeSize |
| 1333 kUserIconLargeSize : kUserIconSize; | 280 : kTrayAvatarSize; |
| 1334 | 281 |
| 1335 content::BrowserContext* context = session_state_delegate-> | 282 content::BrowserContext* context = session_state_delegate-> |
| 1336 GetBrowserContextByIndex(GetTrayIndex()); | 283 GetBrowserContextByIndex(GetTrayIndex()); |
| 1337 avatar_->SetImage(session_state_delegate->GetUserImage(context), | 284 avatar_->SetImage(session_state_delegate->GetUserImage(context), |
| 1338 gfx::Size(icon_size, icon_size)); | 285 gfx::Size(icon_size, icon_size)); |
| 1339 | 286 |
| 1340 // Unit tests might come here with no images for some users. | 287 // Unit tests might come here with no images for some users. |
| 1341 if (avatar_->size().IsEmpty()) | 288 if (avatar_->size().IsEmpty()) |
| 1342 avatar_->SetSize(gfx::Size(icon_size, icon_size)); | 289 avatar_->SetSize(gfx::Size(icon_size, icon_size)); |
| 1343 } | 290 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1356 void TrayUser::UpdateLayoutOfItem() { | 303 void TrayUser::UpdateLayoutOfItem() { |
| 1357 RootWindowController* controller = GetRootWindowController( | 304 RootWindowController* controller = GetRootWindowController( |
| 1358 system_tray()->GetWidget()->GetNativeWindow()->GetRootWindow()); | 305 system_tray()->GetWidget()->GetNativeWindow()->GetRootWindow()); |
| 1359 if (controller && controller->shelf()) { | 306 if (controller && controller->shelf()) { |
| 1360 UpdateAfterShelfAlignmentChange( | 307 UpdateAfterShelfAlignmentChange( |
| 1361 controller->GetShelfLayoutManager()->GetAlignment()); | 308 controller->GetShelfLayoutManager()->GetAlignment()); |
| 1362 } | 309 } |
| 1363 } | 310 } |
| 1364 | 311 |
| 1365 } // namespace ash | 312 } // namespace ash |
| OLD | NEW |