| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/common/system/user/user_view.h" | 5 #include "ash/common/system/user/user_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "ash/common/material_design/material_design_controller.h" | 10 #include "ash/common/material_design/material_design_controller.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "ash/common/system/user/button_from_view.h" | 22 #include "ash/common/system/user/button_from_view.h" |
| 23 #include "ash/common/system/user/login_status.h" | 23 #include "ash/common/system/user/login_status.h" |
| 24 #include "ash/common/system/user/rounded_image_view.h" | 24 #include "ash/common/system/user/rounded_image_view.h" |
| 25 #include "ash/common/system/user/user_card_view.h" | 25 #include "ash/common/system/user/user_card_view.h" |
| 26 #include "ash/common/wm_lookup.h" | 26 #include "ash/common/wm_lookup.h" |
| 27 #include "ash/common/wm_root_window_controller.h" | 27 #include "ash/common/wm_root_window_controller.h" |
| 28 #include "ash/common/wm_shell.h" | 28 #include "ash/common/wm_shell.h" |
| 29 #include "ash/common/wm_window.h" | 29 #include "ash/common/wm_window.h" |
| 30 #include "ash/public/cpp/shell_window_ids.h" | 30 #include "ash/public/cpp/shell_window_ids.h" |
| 31 #include "ash/resources/vector_icons/vector_icons.h" | 31 #include "ash/resources/vector_icons/vector_icons.h" |
| 32 #include "base/optional.h" |
| 32 #include "components/signin/core/account_id/account_id.h" | 33 #include "components/signin/core/account_id/account_id.h" |
| 33 #include "components/user_manager/user_info.h" | 34 #include "components/user_manager/user_info.h" |
| 34 #include "grit/ash_resources.h" | 35 #include "grit/ash_resources.h" |
| 35 #include "grit/ash_strings.h" | 36 #include "grit/ash_strings.h" |
| 36 #include "ui/base/l10n/l10n_util.h" | 37 #include "ui/base/l10n/l10n_util.h" |
| 37 #include "ui/base/resource/resource_bundle.h" | 38 #include "ui/base/resource/resource_bundle.h" |
| 38 #include "ui/gfx/canvas.h" | 39 #include "ui/gfx/canvas.h" |
| 39 #include "ui/gfx/geometry/insets.h" | 40 #include "ui/gfx/geometry/insets.h" |
| 40 #include "ui/gfx/paint_vector_icon.h" | 41 #include "ui/gfx/paint_vector_icon.h" |
| 41 #include "ui/views/controls/button/label_button.h" | 42 #include "ui/views/controls/button/label_button.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 MultiProfileUMA::RecordSwitchActiveUser( | 97 MultiProfileUMA::RecordSwitchActiveUser( |
| 97 MultiProfileUMA::SWITCH_ACTIVE_USER_BY_TRAY); | 98 MultiProfileUMA::SWITCH_ACTIVE_USER_BY_TRAY); |
| 98 delegate->SwitchActiveUser(delegate->GetUserInfo(user_index)->GetAccountId()); | 99 delegate->SwitchActiveUser(delegate->GetUserInfo(user_index)->GetAccountId()); |
| 99 } | 100 } |
| 100 | 101 |
| 101 bool IsMultiProfileSupportedAndUserActive() { | 102 bool IsMultiProfileSupportedAndUserActive() { |
| 102 return WmShell::Get()->delegate()->IsMultiProfilesEnabled() && | 103 return WmShell::Get()->delegate()->IsMultiProfilesEnabled() && |
| 103 !WmShell::Get()->GetSessionStateDelegate()->IsUserSessionBlocked(); | 104 !WmShell::Get()->GetSessionStateDelegate()->IsUserSessionBlocked(); |
| 104 } | 105 } |
| 105 | 106 |
| 107 // Creates the view shown in the user switcher popup ("AddUserMenuOption"). |
| 108 views::View* CreateAddUserView( |
| 109 base::Optional<SessionStateDelegate::AddUserError> error) { |
| 110 DCHECK(UseMd()); |
| 111 auto view = new views::View; |
| 112 auto layout = new views::BoxLayout( |
| 113 views::BoxLayout::kHorizontal, (kMenuButtonSize - kMenuIconSize) / 2, |
| 114 kMenuSeparatorVerticalPadding, kTrayPopupPaddingBetweenItems); |
| 115 layout->set_minimum_cross_axis_size( |
| 116 error ? 56 : GetTrayConstant(TRAY_POPUP_ITEM_MIN_HEIGHT)); |
| 117 view->SetLayoutManager(layout); |
| 118 view->set_background( |
| 119 views::Background::CreateSolidBackground(kBackgroundColor)); |
| 120 |
| 121 if (!error) { |
| 122 auto icon = new views::ImageView(); |
| 123 icon->SetImage( |
| 124 gfx::CreateVectorIcon(kSystemMenuNewUserIcon, kMenuIconColor)); |
| 125 view->AddChildView(icon); |
| 126 } |
| 127 |
| 128 int message_id = IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT; |
| 129 if (error) { |
| 130 switch (*error) { |
| 131 case SessionStateDelegate::ADD_USER_ERROR_NOT_ALLOWED_PRIMARY_USER: |
| 132 message_id = IDS_ASH_STATUS_TRAY_MESSAGE_NOT_ALLOWED_PRIMARY_USER; |
| 133 break; |
| 134 case SessionStateDelegate::ADD_USER_ERROR_MAXIMUM_USERS_REACHED: |
| 135 message_id = IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER; |
| 136 break; |
| 137 case SessionStateDelegate::ADD_USER_ERROR_OUT_OF_USERS: |
| 138 message_id = IDS_ASH_STATUS_TRAY_MESSAGE_OUT_OF_USERS; |
| 139 break; |
| 140 } |
| 141 } |
| 142 |
| 143 auto command_label = new views::Label(l10n_util::GetStringUTF16(message_id)); |
| 144 command_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 145 command_label->SetMultiLine(true); |
| 146 view->AddChildView(command_label); |
| 147 return view; |
| 148 } |
| 149 |
| 106 class UserViewMouseWatcherHost : public views::MouseWatcherHost { | 150 class UserViewMouseWatcherHost : public views::MouseWatcherHost { |
| 107 public: | 151 public: |
| 108 explicit UserViewMouseWatcherHost(const gfx::Rect& screen_area) | 152 explicit UserViewMouseWatcherHost(const gfx::Rect& screen_area) |
| 109 : screen_area_(screen_area) {} | 153 : screen_area_(screen_area) {} |
| 110 ~UserViewMouseWatcherHost() override {} | 154 ~UserViewMouseWatcherHost() override {} |
| 111 | 155 |
| 112 // Implementation of MouseWatcherHost. | 156 // Implementation of MouseWatcherHost. |
| 113 bool Contains(const gfx::Point& screen_point, | 157 bool Contains(const gfx::Point& screen_point, |
| 114 views::MouseWatcherHost::MouseEventType type) override { | 158 views::MouseWatcherHost::MouseEventType type) override { |
| 115 return screen_area_.Contains(screen_point); | 159 return screen_area_.Contains(screen_point); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 ButtonFromView* owner_; | 218 ButtonFromView* owner_; |
| 175 | 219 |
| 176 // The anchor view for targetted bubble messages. | 220 // The anchor view for targetted bubble messages. |
| 177 views::View* anchor_; | 221 views::View* anchor_; |
| 178 | 222 |
| 179 DISALLOW_COPY_AND_ASSIGN(AddUserView); | 223 DISALLOW_COPY_AND_ASSIGN(AddUserView); |
| 180 }; | 224 }; |
| 181 | 225 |
| 182 AddUserView::AddUserView(ButtonFromView* owner) | 226 AddUserView::AddUserView(ButtonFromView* owner) |
| 183 : add_user_(nullptr), owner_(owner), anchor_(nullptr) { | 227 : add_user_(nullptr), owner_(owner), anchor_(nullptr) { |
| 228 DCHECK(!UseMd()); |
| 184 AddContent(); | 229 AddContent(); |
| 185 owner_->ForceBorderVisible(true); | 230 owner_->ForceBorderVisible(true); |
| 186 } | 231 } |
| 187 | 232 |
| 188 AddUserView::~AddUserView() { | 233 AddUserView::~AddUserView() { |
| 189 owner_->ForceBorderVisible(false); | 234 owner_->ForceBorderVisible(false); |
| 190 } | 235 } |
| 191 | 236 |
| 192 gfx::Size AddUserView::GetPreferredSize() const { | 237 gfx::Size AddUserView::GetPreferredSize() const { |
| 193 return owner_->bounds().size(); | 238 return owner_->bounds().size(); |
| 194 } | 239 } |
| 195 | 240 |
| 196 void AddUserView::AddContent() { | 241 void AddUserView::AddContent() { |
| 197 SetLayoutManager(new views::FillLayout()); | 242 SetLayoutManager(new views::FillLayout()); |
| 198 set_background(views::Background::CreateSolidBackground(kBackgroundColor)); | 243 set_background(views::Background::CreateSolidBackground(kBackgroundColor)); |
| 199 | 244 |
| 200 add_user_ = new views::View; | 245 add_user_ = new views::View; |
| 201 add_user_->SetLayoutManager(new views::BoxLayout( | 246 add_user_->SetLayoutManager(new views::BoxLayout( |
| 202 views::BoxLayout::kHorizontal, 0, 0, kTrayPopupPaddingBetweenItems)); | 247 views::BoxLayout::kHorizontal, 0, 0, kTrayPopupPaddingBetweenItems)); |
| 203 AddChildViewAt(add_user_, 0); | 248 AddChildViewAt(add_user_, 0); |
| 204 | 249 |
| 205 // Add the icon which is also the anchor for messages. | 250 // Add the icon which is also the anchor for messages. |
| 206 if (UseMd()) { | 251 add_user_->SetBorder( |
| 207 views::ImageView* icon = new views::ImageView(); | 252 views::CreateEmptyBorder(0, kTrayUserTileHoverBorderInset, 0, 0)); |
| 208 icon->SetImage( | 253 RoundedImageView* icon = new RoundedImageView(kTrayRoundedBorderRadius, true); |
| 209 gfx::CreateVectorIcon(kSystemMenuNewUserIcon, kMenuIconColor)); | 254 anchor_ = icon; |
| 210 icon->SetBorder(views::CreateEmptyBorder(gfx::Insets( | 255 icon->SetImage(*ui::ResourceBundle::GetSharedInstance() |
| 211 (GetTrayConstant(TRAY_POPUP_ITEM_MAIN_IMAGE_CONTAINER_WIDTH) - | 256 .GetImageNamed(IDR_AURA_UBER_TRAY_ADD_MULTIPROFILE_USER) |
| 212 icon->GetPreferredSize().width()) / | 257 .ToImageSkia(), |
| 213 2))); | 258 gfx::Size(kTrayItemSize, kTrayItemSize)); |
| 214 anchor_ = icon; | 259 add_user_->AddChildView(icon); |
| 215 add_user_->AddChildView(icon); | |
| 216 } else { | |
| 217 add_user_->SetBorder( | |
| 218 views::CreateEmptyBorder(0, kTrayUserTileHoverBorderInset, 0, 0)); | |
| 219 RoundedImageView* icon = | |
| 220 new RoundedImageView(kTrayRoundedBorderRadius, true); | |
| 221 anchor_ = icon; | |
| 222 icon->SetImage(*ui::ResourceBundle::GetSharedInstance() | |
| 223 .GetImageNamed(IDR_AURA_UBER_TRAY_ADD_MULTIPROFILE_USER) | |
| 224 .ToImageSkia(), | |
| 225 gfx::Size(kTrayItemSize, kTrayItemSize)); | |
| 226 add_user_->AddChildView(icon); | |
| 227 } | |
| 228 | 260 |
| 229 // Add the command text. | 261 // Add the command text. |
| 230 views::Label* command_label = new views::Label( | 262 views::Label* command_label = new views::Label( |
| 231 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); | 263 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); |
| 232 command_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 264 command_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 233 add_user_->AddChildView(command_label); | 265 add_user_->AddChildView(command_label); |
| 234 } | 266 } |
| 235 | 267 |
| 268 // This border reserves 4dp above and 8dp below and paints a horizontal |
| 269 // separator 3dp below the host view. |
| 270 class ActiveUserBorder : public views::Border { |
| 271 public: |
| 272 ActiveUserBorder() {} |
| 273 ~ActiveUserBorder() override {} |
| 274 |
| 275 // views::Border: |
| 276 void Paint(const views::View& view, gfx::Canvas* canvas) override { |
| 277 canvas->FillRect( |
| 278 gfx::Rect( |
| 279 0, view.height() - kMenuSeparatorVerticalPadding - kSeparatorWidth, |
| 280 view.width(), kSeparatorWidth), |
| 281 kHorizontalSeparatorColor); |
| 282 } |
| 283 |
| 284 gfx::Insets GetInsets() const override { |
| 285 return gfx::Insets(kMenuSeparatorVerticalPadding, 0, |
| 286 kMenuSeparatorVerticalPadding * 2, 0); |
| 287 } |
| 288 |
| 289 gfx::Size GetMinimumSize() const override { return gfx::Size(); } |
| 290 |
| 291 private: |
| 292 DISALLOW_COPY_AND_ASSIGN(ActiveUserBorder); |
| 293 }; |
| 294 |
| 236 } // namespace | 295 } // namespace |
| 237 | 296 |
| 238 UserView::UserView(SystemTrayItem* owner, LoginStatus login, UserIndex index) | 297 UserView::UserView(SystemTrayItem* owner, LoginStatus login, UserIndex index) |
| 239 : user_index_(index), | 298 : user_index_(index), |
| 240 user_card_view_(nullptr), | 299 user_card_view_(nullptr), |
| 241 owner_(owner), | 300 owner_(owner), |
| 242 is_user_card_button_(false), | 301 is_user_card_button_(false), |
| 243 logout_button_(nullptr), | 302 logout_button_(nullptr), |
| 244 add_user_enabled_(true), | 303 add_user_enabled_(true), |
| 245 focus_manager_(nullptr) { | 304 focus_manager_(nullptr) { |
| 246 CHECK_NE(LoginStatus::NOT_LOGGED_IN, login); | 305 CHECK_NE(LoginStatus::NOT_LOGGED_IN, login); |
| 247 if (!UseMd() && !index && login == LoginStatus::PUBLIC) { | 306 if (!UseMd() && !index && login == LoginStatus::PUBLIC) { |
| 248 // Public user gets a yellow bg. | 307 // Public user gets a yellow bg. |
| 249 set_background(views::Background::CreateSolidBackground( | 308 set_background(views::Background::CreateSolidBackground( |
| 250 kPublicAccountBackgroundColor)); | 309 kPublicAccountBackgroundColor)); |
| 251 } | 310 } |
| 252 // The logout button must be added before the user card so that the user card | 311 // The logout button must be added before the user card so that the user card |
| 253 // can correctly calculate the remaining available width. | 312 // can correctly calculate the remaining available width. |
| 254 // Note that only the current multiprofile user gets a button. | 313 // Note that only the current multiprofile user gets a button. |
| 255 if (IsActiveUser()) | 314 if (IsActiveUser()) |
| 256 AddLogoutButton(login); | 315 AddLogoutButton(login); |
| 257 AddUserCard(login); | 316 AddUserCard(login); |
| 258 | 317 |
| 259 if (UseMd()) { | 318 if (UseMd()) { |
| 260 auto* layout = new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0); | 319 auto* layout = new views::BoxLayout(views::BoxLayout::kHorizontal, |
| 261 if (IsActiveUser()) { | 320 kMenuExtraMarginFromLeftEdge, 0, 0); |
| 262 layout->set_inside_border_insets(gfx::Insets( | |
| 263 0, kMenuExtraMarginFromLeftEdge, 0, kMenuExtraMarginFromLeftEdge)); | |
| 264 } | |
| 265 | |
| 266 SetLayoutManager(layout); | 321 SetLayoutManager(layout); |
| 267 layout->set_cross_axis_alignment( | 322 layout->set_cross_axis_alignment( |
| 268 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); | 323 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); |
| 269 layout->SetFlexForView(user_card_view_, 1); | 324 layout->SetFlexForView(user_card_view_, 1); |
| 270 | 325 |
| 271 if (IsActiveUser()) { | 326 if (IsActiveUser()) |
| 272 SetBorder(views::CreatePaddedBorder( | 327 SetBorder(base::MakeUnique<ActiveUserBorder>()); |
| 273 views::CreateSolidSidedBorder(0, 0, kSeparatorWidth, 0, | |
| 274 kSeparatorColor), | |
| 275 gfx::Insets(kMenuSeparatorVerticalPadding, 0, | |
| 276 kMenuSeparatorVerticalPadding - kSeparatorWidth, 0))); | |
| 277 } | |
| 278 } | 328 } |
| 279 } | 329 } |
| 280 | 330 |
| 281 UserView::~UserView() { | 331 UserView::~UserView() { |
| 282 RemoveAddUserMenuOption(); | 332 RemoveAddUserMenuOption(); |
| 283 } | 333 } |
| 284 | 334 |
| 285 void UserView::MouseMovedOutOfHost() { | 335 void UserView::MouseMovedOutOfHost() { |
| 286 DCHECK(!UseMd()); | 336 DCHECK(!UseMd()); |
| 287 RemoveAddUserMenuOption(); | 337 RemoveAddUserMenuOption(); |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 if (clickable) { | 563 if (clickable) { |
| 514 views::View* contents_view = user_card_view_; | 564 views::View* contents_view = user_card_view_; |
| 515 auto* button = | 565 auto* button = |
| 516 new ButtonFromView(contents_view, this, false, gfx::Insets()); | 566 new ButtonFromView(contents_view, this, false, gfx::Insets()); |
| 517 if (IsActiveUser()) | 567 if (IsActiveUser()) |
| 518 button->set_ink_drop_insets(gfx::Insets(kTrayPopupInkDropInset)); | 568 button->set_ink_drop_insets(gfx::Insets(kTrayPopupInkDropInset)); |
| 519 user_card_view_ = button; | 569 user_card_view_ = button; |
| 520 is_user_card_button_ = true; | 570 is_user_card_button_ = true; |
| 521 } | 571 } |
| 522 AddChildViewAt(user_card_view_, 0); | 572 AddChildViewAt(user_card_view_, 0); |
| 523 // Card for supervised user can consume more space than currently | |
| 524 // available. In that case we should increase system bubble's width. | |
| 525 // TODO(estade,sgabriel): do we need this? | |
| 526 if (login == LoginStatus::PUBLIC) { | |
| 527 owner_->system_tray()->GetSystemBubble()->bubble_view()->SetWidth( | |
| 528 GetPreferredSize().width()); | |
| 529 } | |
| 530 } | 573 } |
| 531 | 574 |
| 532 void UserView::ToggleAddUserMenuOption() { | 575 void UserView::ToggleAddUserMenuOption() { |
| 533 if (add_menu_option_.get()) { | 576 if (add_menu_option_.get()) { |
| 534 RemoveAddUserMenuOption(); | 577 RemoveAddUserMenuOption(); |
| 535 return; | 578 return; |
| 536 } | 579 } |
| 537 | 580 |
| 538 // Note: We do not need to install a global event handler to delete this | 581 // Note: We do not need to install a global event handler to delete this |
| 539 // item since it will destroyed automatically before the menu / user menu item | 582 // item since it will destroyed automatically before the menu / user menu item |
| (...skipping 14 matching lines...) Expand all Loading... |
| 554 ->ConfigureWidgetInitParamsForContainer( | 597 ->ConfigureWidgetInitParamsForContainer( |
| 555 add_menu_option_.get(), kShellWindowId_DragImageAndTooltipContainer, | 598 add_menu_option_.get(), kShellWindowId_DragImageAndTooltipContainer, |
| 556 ¶ms); | 599 ¶ms); |
| 557 add_menu_option_->Init(params); | 600 add_menu_option_->Init(params); |
| 558 | 601 |
| 559 const SessionStateDelegate* delegate = | 602 const SessionStateDelegate* delegate = |
| 560 WmShell::Get()->GetSessionStateDelegate(); | 603 WmShell::Get()->GetSessionStateDelegate(); |
| 561 SessionStateDelegate::AddUserError add_user_error; | 604 SessionStateDelegate::AddUserError add_user_error; |
| 562 add_user_enabled_ = delegate->CanAddUserToMultiProfile(&add_user_error); | 605 add_user_enabled_ = delegate->CanAddUserToMultiProfile(&add_user_error); |
| 563 | 606 |
| 564 AddUserView* add_user_view = | 607 if (UseMd()) { |
| 565 new AddUserView(static_cast<ButtonFromView*>(user_card_view_)); | 608 base::Optional<SessionStateDelegate::AddUserError> error; |
| 566 ButtonFromView* button = new ButtonFromView( | 609 if (!add_user_enabled_) |
| 567 add_user_view, add_user_enabled_ ? this : nullptr, | 610 error = add_user_error; |
| 568 !UseMd() && add_user_enabled_, gfx::Insets(UseMd() ? 0 : 1)); | 611 ButtonFromView* button = new ButtonFromView( |
| 569 if (UseMd()) | 612 CreateAddUserView(error), add_user_enabled_ ? this : nullptr, false, |
| 613 gfx::Insets()); |
| 570 button->set_ink_drop_insets(gfx::Insets(kTrayPopupInkDropInset)); | 614 button->set_ink_drop_insets(gfx::Insets(kTrayPopupInkDropInset)); |
| 571 button->SetAccessibleName( | 615 button->SetAccessibleName( |
| 572 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); | 616 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); |
| 573 button->ForceBorderVisible(true); | 617 button->ForceBorderVisible(true); |
| 574 | 618 |
| 575 if (UseMd()) { | |
| 576 // Position the widget on top of the user card view (which is still in the | 619 // Position the widget on top of the user card view (which is still in the |
| 577 // system menu). The top half of the widget will be transparent to allow | 620 // system menu). The top half of the widget will be transparent to allow |
| 578 // the active user to show through. | 621 // the active user to show through. |
| 579 gfx::Rect bounds = user_card_view_->GetBoundsInScreen(); | 622 gfx::Rect bounds = user_card_view_->GetBoundsInScreen(); |
| 580 bounds.set_width(bounds.width() + kSeparatorWidth); | 623 bounds.set_width(bounds.width() + kSeparatorWidth); |
| 581 int row_height = bounds.height(); | 624 int row_height = bounds.height(); |
| 582 bounds.set_height(row_height * 2); | |
| 583 add_menu_option_->SetBounds(bounds); | |
| 584 | 625 |
| 585 views::View* container = new AddUserWidgetContents( | 626 views::View* container = new AddUserWidgetContents( |
| 586 base::Bind(&UserView::RemoveAddUserMenuOption, base::Unretained(this))); | 627 base::Bind(&UserView::RemoveAddUserMenuOption, base::Unretained(this))); |
| 587 container->SetBorder(views::CreatePaddedBorder( | 628 container->SetBorder(views::CreatePaddedBorder( |
| 588 views::CreateSolidSidedBorder(0, 0, 0, kSeparatorWidth, | 629 views::CreateSolidSidedBorder(0, 0, 0, kSeparatorWidth, |
| 589 kBackgroundColor), | 630 kBackgroundColor), |
| 590 gfx::Insets(row_height, 0, 0, 0))); | 631 gfx::Insets(row_height, 0, 0, 0))); |
| 591 container->SetLayoutManager(new views::FillLayout()); | 632 container->SetLayoutManager(new views::FillLayout()); |
| 592 container->AddChildView(button); | 633 container->AddChildView(button); |
| 593 add_menu_option_->SetContentsView(container); | 634 add_menu_option_->SetContentsView(container); |
| 635 |
| 636 bounds.set_height(container->GetPreferredSize().height()); |
| 637 add_menu_option_->SetBounds(bounds); |
| 638 |
| 639 // Show the content. |
| 640 add_menu_option_->SetAlwaysOnTop(true); |
| 641 add_menu_option_->Show(); |
| 642 |
| 643 // We activate the entry automatically if invoked with focus. |
| 644 if (add_user_enabled_ && user_card_view_->HasFocus()) { |
| 645 button->GetFocusManager()->SetFocusedView(button); |
| 646 user_card_view_->GetFocusManager()->SetFocusedView(button); |
| 647 } |
| 594 } else { | 648 } else { |
| 649 AddUserView* add_user_view = |
| 650 new AddUserView(static_cast<ButtonFromView*>(user_card_view_)); |
| 651 ButtonFromView* button = |
| 652 new ButtonFromView(add_user_view, add_user_enabled_ ? this : nullptr, |
| 653 add_user_enabled_, gfx::Insets(1)); |
| 654 button->SetAccessibleName( |
| 655 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); |
| 656 button->ForceBorderVisible(true); |
| 657 |
| 595 add_menu_option_->SetOpacity(1.f); | 658 add_menu_option_->SetOpacity(1.f); |
| 596 add_menu_option_->SetContentsView(button); | 659 add_menu_option_->SetContentsView(button); |
| 597 // Position it below our user card. | 660 // Position it below our user card. |
| 598 gfx::Rect bounds = user_card_view_->GetBoundsInScreen(); | 661 gfx::Rect bounds = user_card_view_->GetBoundsInScreen(); |
| 599 bounds.set_y(bounds.y() + bounds.height()); | 662 bounds.set_y(bounds.y() + bounds.height()); |
| 600 add_menu_option_->SetBounds(bounds); | 663 add_menu_option_->SetBounds(bounds); |
| 601 } | |
| 602 | 664 |
| 603 // Show the content. | 665 // Show the content. |
| 604 add_menu_option_->SetAlwaysOnTop(true); | 666 add_menu_option_->SetAlwaysOnTop(true); |
| 605 add_menu_option_->Show(); | 667 add_menu_option_->Show(); |
| 606 | 668 |
| 607 if (add_user_enabled_) { | 669 if (add_user_enabled_) { |
| 608 // We activate the entry automatically if invoked with focus. | 670 // We activate the entry automatically if invoked with focus. |
| 609 if (user_card_view_->HasFocus()) { | 671 if (user_card_view_->HasFocus()) { |
| 610 button->GetFocusManager()->SetFocusedView(button); | 672 button->GetFocusManager()->SetFocusedView(button); |
| 611 user_card_view_->GetFocusManager()->SetFocusedView(button); | 673 user_card_view_->GetFocusManager()->SetFocusedView(button); |
| 674 } |
| 675 } else { |
| 676 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
| 677 int message_id = 0; |
| 678 switch (add_user_error) { |
| 679 case SessionStateDelegate::ADD_USER_ERROR_NOT_ALLOWED_PRIMARY_USER: |
| 680 message_id = IDS_ASH_STATUS_TRAY_MESSAGE_NOT_ALLOWED_PRIMARY_USER; |
| 681 break; |
| 682 case SessionStateDelegate::ADD_USER_ERROR_MAXIMUM_USERS_REACHED: |
| 683 message_id = IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER; |
| 684 break; |
| 685 case SessionStateDelegate::ADD_USER_ERROR_OUT_OF_USERS: |
| 686 message_id = IDS_ASH_STATUS_TRAY_MESSAGE_OUT_OF_USERS; |
| 687 break; |
| 688 default: |
| 689 NOTREACHED() << "Unknown adding user error " << add_user_error; |
| 690 } |
| 691 |
| 692 popup_message_.reset(new PopupMessage( |
| 693 bundle.GetLocalizedString( |
| 694 IDS_ASH_STATUS_TRAY_CAPTION_CANNOT_ADD_USER), |
| 695 bundle.GetLocalizedString(message_id), PopupMessage::ICON_WARNING, |
| 696 add_user_view->anchor(), views::BubbleBorder::TOP_LEFT, |
| 697 gfx::Size(parent()->bounds().width() - kPopupMessageOffset, 0), |
| 698 2 * kPopupMessageOffset)); |
| 612 } | 699 } |
| 613 } else { | |
| 614 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | |
| 615 int message_id = 0; | |
| 616 switch (add_user_error) { | |
| 617 case SessionStateDelegate::ADD_USER_ERROR_NOT_ALLOWED_PRIMARY_USER: | |
| 618 message_id = IDS_ASH_STATUS_TRAY_MESSAGE_NOT_ALLOWED_PRIMARY_USER; | |
| 619 break; | |
| 620 case SessionStateDelegate::ADD_USER_ERROR_MAXIMUM_USERS_REACHED: | |
| 621 message_id = IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER; | |
| 622 break; | |
| 623 case SessionStateDelegate::ADD_USER_ERROR_OUT_OF_USERS: | |
| 624 message_id = IDS_ASH_STATUS_TRAY_MESSAGE_OUT_OF_USERS; | |
| 625 break; | |
| 626 default: | |
| 627 NOTREACHED() << "Unknown adding user error " << add_user_error; | |
| 628 } | |
| 629 | |
| 630 popup_message_.reset(new PopupMessage( | |
| 631 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAPTION_CANNOT_ADD_USER), | |
| 632 bundle.GetLocalizedString(message_id), PopupMessage::ICON_WARNING, | |
| 633 add_user_view->anchor(), views::BubbleBorder::TOP_LEFT, | |
| 634 gfx::Size(parent()->bounds().width() - kPopupMessageOffset, 0), | |
| 635 2 * kPopupMessageOffset)); | |
| 636 } | |
| 637 if (!UseMd()) { | |
| 638 // Find the screen area which encloses both elements and sets then a mouse | 700 // Find the screen area which encloses both elements and sets then a mouse |
| 639 // watcher which will close the "menu". | 701 // watcher which will close the "menu". |
| 640 gfx::Rect area = user_card_view_->GetBoundsInScreen(); | 702 gfx::Rect area = user_card_view_->GetBoundsInScreen(); |
| 641 area.set_height(2 * area.height()); | 703 area.set_height(2 * area.height()); |
| 642 mouse_watcher_.reset( | 704 mouse_watcher_.reset( |
| 643 new views::MouseWatcher(new UserViewMouseWatcherHost(area), this)); | 705 new views::MouseWatcher(new UserViewMouseWatcherHost(area), this)); |
| 644 mouse_watcher_->Start(); | 706 mouse_watcher_->Start(); |
| 645 } | 707 } |
| 646 // Install a listener to focus changes so that we can remove the card when | 708 // Install a listener to focus changes so that we can remove the card when |
| 647 // the focus gets changed. When called through the destruction of the bubble, | 709 // the focus gets changed. When called through the destruction of the bubble, |
| 648 // the FocusManager cannot be determined anymore and we remember it here. | 710 // the FocusManager cannot be determined anymore and we remember it here. |
| 649 focus_manager_ = user_card_view_->GetFocusManager(); | 711 focus_manager_ = user_card_view_->GetFocusManager(); |
| 650 focus_manager_->AddFocusChangeListener(this); | 712 focus_manager_->AddFocusChangeListener(this); |
| 651 } | 713 } |
| 652 | 714 |
| 653 void UserView::RemoveAddUserMenuOption() { | 715 void UserView::RemoveAddUserMenuOption() { |
| 654 if (!add_menu_option_.get()) | 716 if (!add_menu_option_.get()) |
| 655 return; | 717 return; |
| 656 focus_manager_->RemoveFocusChangeListener(this); | 718 focus_manager_->RemoveFocusChangeListener(this); |
| 657 focus_manager_ = nullptr; | 719 focus_manager_ = nullptr; |
| 658 if (user_card_view_->GetFocusManager()) | 720 if (user_card_view_->GetFocusManager()) |
| 659 user_card_view_->GetFocusManager()->ClearFocus(); | 721 user_card_view_->GetFocusManager()->ClearFocus(); |
| 660 popup_message_.reset(); | 722 popup_message_.reset(); |
| 661 mouse_watcher_.reset(); | 723 mouse_watcher_.reset(); |
| 662 add_menu_option_.reset(); | 724 add_menu_option_.reset(); |
| 663 } | 725 } |
| 664 | 726 |
| 665 } // namespace tray | 727 } // namespace tray |
| 666 } // namespace ash | 728 } // namespace ash |
| OLD | NEW |