1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// found in the LICENSE file. 4a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 5a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/system/user/user_view.h" 6a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 7a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include <algorithm> 8a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 9a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/multi_profile_uma.h" 10a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/popup_message.h" 115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/session/session_state_delegate.h" 12a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/shell.h" 13a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/shell_delegate.h" 14a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/system/tray/system_tray.h" 15a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/system/tray/system_tray_delegate.h" 16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/system/tray/tray_popup_label_button.h" 17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/system/tray/tray_popup_label_button_border.h" 18a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/system/user/button_from_view.h" 19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/system/user/config.h" 20a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/system/user/rounded_image_view.h" 21a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/system/user/user_card_view.h" 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/user_manager/user_info.h" 23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "grit/ash_resources.h" 24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "grit/ash_strings.h" 25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/base/l10n/l10n_util.h" 26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/base/resource/resource_bundle.h" 27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/views/layout/fill_layout.h" 28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/views/painter.h" 29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/wm/core/shadow_types.h" 30a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace ash { 32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace tray { 33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace { 35a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst int kPublicAccountLogoutButtonBorderImagesNormal[] = { 37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, 38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND, 39a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND, 40a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, 41a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND, 42a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND, 43a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, 44a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND, 45a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND, 46a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}; 47a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 48a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst int kPublicAccountLogoutButtonBorderImagesHovered[] = { 49a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, 50a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, 51a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, 52a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, 53a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_LABEL_BUTTON_HOVER_BACKGROUND, 54a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, 55a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, 56a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, 57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, 58a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}; 59a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 60a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// When a hover border is used, it is starting this many pixels before the icon 61a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// position. 62a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst int kTrayUserTileHoverBorderInset = 10; 63a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 64a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Offsetting the popup message relative to the tray menu. 65a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst int kPopupMessageOffset = 25; 66a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Switch to a user with the given |user_index|. 68a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid SwitchUser(ash::MultiProfileIndex user_index) { 69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Do not switch users when the log screen is presented. 70a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (ash::Shell::GetInstance() 71a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ->session_state_delegate() 72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ->IsUserSessionBlocked()) 73a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 74a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DCHECK(user_index > 0); 76a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ash::SessionStateDelegate* delegate = 77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ash::Shell::GetInstance()->session_state_delegate(); 78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ash::MultiProfileUMA::RecordSwitchActiveUser( 79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ash::MultiProfileUMA::SWITCH_ACTIVE_USER_BY_TRAY); 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu delegate->SwitchActiveUser(delegate->GetUserInfo(user_index)->GetUserID()); 81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass LogoutButton : public TrayPopupLabelButton { 84a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public: 85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // If |placeholder| is true, button is used as placeholder. That means that 86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // button is inactive and is not painted, but consume the same ammount of 87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // space, as if it was painted. 88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch LogoutButton(views::ButtonListener* listener, 89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const base::string16& text, 90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bool placeholder) 91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : TrayPopupLabelButton(listener, text), placeholder_(placeholder) { 92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetEnabled(!placeholder_); 93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch virtual ~LogoutButton() {} 96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch private: 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void Paint(gfx::Canvas* canvas, 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const views::CullSet& cull_set) OVERRIDE { 100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Just skip paint if this button used as a placeholder. 101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!placeholder_) 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TrayPopupLabelButton::Paint(canvas, cull_set); 103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bool placeholder_; 106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DISALLOW_COPY_AND_ASSIGN(LogoutButton); 107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}; 108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass UserViewMouseWatcherHost : public views::MouseWatcherHost { 110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public: 111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch explicit UserViewMouseWatcherHost(const gfx::Rect& screen_area) 112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : screen_area_(screen_area) {} 113a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch virtual ~UserViewMouseWatcherHost() {} 114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Implementation of MouseWatcherHost. 116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch virtual bool Contains(const gfx::Point& screen_point, 117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::MouseWatcherHost::MouseEventType type) OVERRIDE { 118a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return screen_area_.Contains(screen_point); 119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 120a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 121a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch private: 122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect screen_area_; 123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DISALLOW_COPY_AND_ASSIGN(UserViewMouseWatcherHost); 125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}; 126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// The menu item view which gets shown when the user clicks in multi profile 128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// mode onto the user item. 129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass AddUserView : public views::View { 130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public: 131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // The |owner| is the view for which this view gets created. 132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AddUserView(ButtonFromView* owner); 133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch virtual ~AddUserView(); 134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 135a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Get the anchor view for a message. 136a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::View* anchor() { return anchor_; } 137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 138a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch private: 139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Overridden from views::View. 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual gfx::Size GetPreferredSize() const OVERRIDE; 141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Create the additional client content for this item. 143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch void AddContent(); 144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // This is the content we create and show. 146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::View* add_user_; 147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 148a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // This is the owner view of this item. 149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ButtonFromView* owner_; 150a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // The anchor view for targetted bubble messages. 152a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::View* anchor_; 153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 154a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DISALLOW_COPY_AND_ASSIGN(AddUserView); 155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}; 156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 157a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochAddUserView::AddUserView(ButtonFromView* owner) 158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : add_user_(NULL), owner_(owner), anchor_(NULL) { 159a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AddContent(); 160a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch owner_->ForceBorderVisible(true); 161a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 162a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 163a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochAddUserView::~AddUserView() { 164a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch owner_->ForceBorderVisible(false); 165a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 166a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size AddUserView::GetPreferredSize() const { 168a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return owner_->bounds().size(); 169a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 171a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid AddUserView::AddContent() { 172a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetLayoutManager(new views::FillLayout()); 173a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch set_background(views::Background::CreateSolidBackground(kBackgroundColor)); 174a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 175a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_user_ = new views::View; 176a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_user_->SetBorder(views::Border::CreateEmptyBorder( 177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 0, kTrayUserTileHoverBorderInset, 0, 0)); 178a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 179a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_user_->SetLayoutManager(new views::BoxLayout( 180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::BoxLayout::kHorizontal, 0, 0, kTrayPopupPaddingBetweenItems)); 181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AddChildViewAt(add_user_, 0); 182a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 183a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Add the [+] icon which is also the anchor for messages. 184a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch RoundedImageView* icon = new RoundedImageView(kTrayAvatarCornerRadius, true); 185a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch anchor_ = icon; 186a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch icon->SetImage(*ui::ResourceBundle::GetSharedInstance() 187a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch .GetImageNamed(IDR_AURA_UBER_TRAY_ADD_MULTIPROFILE_USER) 188a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch .ToImageSkia(), 189a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Size(kTrayAvatarSize, kTrayAvatarSize)); 190a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_user_->AddChildView(icon); 191a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 192a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Add the command text. 193a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::Label* command_label = new views::Label( 194a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); 195a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch command_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 196a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_user_->AddChildView(command_label); 197a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 198a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 199a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} // namespace 200a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 201a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochUserView::UserView(SystemTrayItem* owner, 202a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch user::LoginStatus login, 203a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch MultiProfileIndex index, 204a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bool for_detailed_view) 205a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : multiprofile_index_(index), 206a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch user_card_view_(NULL), 207a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch owner_(owner), 208a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch is_user_card_button_(false), 209a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch logout_button_(NULL), 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci add_user_enabled_(true), 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for_detailed_view_(for_detailed_view), 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch focus_manager_(NULL) { 213a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch CHECK_NE(user::LOGGED_IN_NONE, login); 214a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!index) { 215a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Only the logged in user will have a background. All other users will have 216a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // to allow the TrayPopupContainer highlighting the menu line. 217a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch set_background(views::Background::CreateSolidBackground( 218a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch login == user::LOGGED_IN_PUBLIC ? kPublicAccountBackgroundColor 219a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : kBackgroundColor)); 220a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 221a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetLayoutManager(new views::BoxLayout( 222a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::BoxLayout::kHorizontal, 0, 0, kTrayPopupPaddingBetweenItems)); 223a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // The logout button must be added before the user card so that the user card 224a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // can correctly calculate the remaining available width. 225a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Note that only the current multiprofile user gets a button. 226a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!multiprofile_index_) 227a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AddLogoutButton(login); 228a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AddUserCard(login); 229a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 230a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 231116680a4aac90f2aa7413d9095a592090648e557Ben MurdochUserView::~UserView() { 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RemoveAddUserMenuOption(); 233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 234a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 235a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid UserView::MouseMovedOutOfHost() { 236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RemoveAddUserMenuOption(); 237a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 238a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 239a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochTrayUser::TestState UserView::GetStateForTest() const { 240a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (add_menu_option_.get()) { 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return add_user_enabled_ ? TrayUser::ACTIVE : TrayUser::ACTIVE_BUT_DISABLED; 242a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 243a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 244a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!is_user_card_button_) 245a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return TrayUser::SHOWN; 246a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 247a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return static_cast<ButtonFromView*>(user_card_view_)->is_hovered_for_test() 248a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ? TrayUser::HOVERED 249a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : TrayUser::SHOWN; 250a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 251a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 252a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochgfx::Rect UserView::GetBoundsInScreenOfUserButtonForTest() { 253a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DCHECK(user_card_view_); 254a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return user_card_view_->GetBoundsInScreen(); 255a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 256a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size UserView::GetPreferredSize() const { 258a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Size size = views::View::GetPreferredSize(); 259a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Only the active user panel will be forced to a certain height. 260a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!multiprofile_index_) { 261a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch size.set_height( 262a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::max(size.height(), kTrayPopupItemHeight + GetInsets().height())); 263a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 264a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return size; 265a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 266a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int UserView::GetHeightForWidth(int width) const { 268a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return GetPreferredSize().height(); 269a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 270a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 271a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid UserView::Layout() { 272a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect contents_area(GetContentsBounds()); 273a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (user_card_view_ && logout_button_) { 274a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Give the logout button the space it requests. 275a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect logout_area = contents_area; 276a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch logout_area.ClampToCenteredSize(logout_button_->GetPreferredSize()); 277a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch logout_area.set_x(contents_area.right() - logout_area.width()); 278a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 279a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Give the remaining space to the user card. 280a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect user_card_area = contents_area; 281a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int remaining_width = contents_area.width() - logout_area.width(); 282a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (IsMultiProfileSupportedAndUserActive() || 283a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IsMultiAccountSupportedAndUserActive()) { 284010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // In multiprofile/multiaccount case |user_card_view_| and 285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // |logout_button_| have to have the same height. 286a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int y = std::min(user_card_area.y(), logout_area.y()); 287a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int height = std::max(user_card_area.height(), logout_area.height()); 288a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch logout_area.set_y(y); 289a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch logout_area.set_height(height); 290a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch user_card_area.set_y(y); 291a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch user_card_area.set_height(height); 292a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 293a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // In multiprofile mode we have also to increase the size of the card by 294a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // the size of the border to make it overlap with the logout button. 295a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch user_card_area.set_width(std::max(0, remaining_width + 1)); 296a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 297a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // To make the logout button symmetrical with the user card we also make 298a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // the button longer by the same size the hover area in front of the icon 299a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // got inset. 300a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch logout_area.set_width(logout_area.width() + 301a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch kTrayUserTileHoverBorderInset); 302a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else { 303a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // In all other modes we have to make sure that there is enough spacing 304a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // between the two. 305a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch remaining_width -= kTrayPopupPaddingBetweenItems; 306a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 307a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch user_card_area.set_width(remaining_width); 308a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch user_card_view_->SetBoundsRect(user_card_area); 309a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch logout_button_->SetBoundsRect(logout_area); 310a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else if (user_card_view_) { 311a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch user_card_view_->SetBoundsRect(contents_area); 312a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else if (logout_button_) { 313a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch logout_button_->SetBoundsRect(contents_area); 314a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 315a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 316a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 317a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid UserView::ButtonPressed(views::Button* sender, const ui::Event& event) { 318a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (sender == logout_button_) { 319a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch Shell::GetInstance()->metrics()->RecordUserMetricsAction( 320a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ash::UMA_STATUS_AREA_SIGN_OUT); 321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RemoveAddUserMenuOption(); 322a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch Shell::GetInstance()->system_tray_delegate()->SignOut(); 323a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else if (sender == user_card_view_ && !multiprofile_index_ && 324a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IsMultiAccountSupportedAndUserActive()) { 325a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch owner_->TransitionDetailedView(); 326a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else if (sender == user_card_view_ && 327a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IsMultiProfileSupportedAndUserActive()) { 328a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!multiprofile_index_) { 329a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ToggleAddUserMenuOption(); 330a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else { 331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RemoveAddUserMenuOption(); 332a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SwitchUser(multiprofile_index_); 333a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Since the user list is about to change the system menu should get 334a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // closed. 335a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch owner_->system_tray()->CloseSystemBubble(); 336a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 337a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else if (add_menu_option_.get() && 338a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch sender == add_menu_option_->GetContentsView()) { 339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RemoveAddUserMenuOption(); 340a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Let the user add another account to the session. 341a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch MultiProfileUMA::RecordSigninUser(MultiProfileUMA::SIGNIN_USER_BY_TRAY); 342a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch Shell::GetInstance()->system_tray_delegate()->ShowUserLogin(); 343a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch owner_->system_tray()->CloseSystemBubble(); 344a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else { 345a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch NOTREACHED(); 346a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 347a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 348a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 349116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid UserView::OnWillChangeFocus(View* focused_before, View* focused_now) { 350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (focused_now) 351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RemoveAddUserMenuOption(); 352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 354116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid UserView::OnDidChangeFocus(View* focused_before, View* focused_now) { 355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Nothing to do here. 356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 358a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid UserView::AddLogoutButton(user::LoginStatus login) { 359a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const base::string16 title = 360a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch user::GetLocalizedSignOutStringForStatus(login, true); 361a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch TrayPopupLabelButton* logout_button = 362a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch new LogoutButton(this, title, for_detailed_view_); 363a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch logout_button->SetAccessibleName(title); 364a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch logout_button_ = logout_button; 365a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // In public account mode, the logout button border has a custom color. 366a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (login == user::LOGGED_IN_PUBLIC) { 367a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch scoped_ptr<TrayPopupLabelButtonBorder> border( 368a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch new TrayPopupLabelButtonBorder()); 369a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch border->SetPainter(false, 370a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::Button::STATE_NORMAL, 371a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::Painter::CreateImageGridPainter( 372a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch kPublicAccountLogoutButtonBorderImagesNormal)); 373a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch border->SetPainter(false, 374a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::Button::STATE_HOVERED, 375a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::Painter::CreateImageGridPainter( 376a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch kPublicAccountLogoutButtonBorderImagesHovered)); 377a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch border->SetPainter(false, 378a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::Button::STATE_PRESSED, 379a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::Painter::CreateImageGridPainter( 380a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch kPublicAccountLogoutButtonBorderImagesHovered)); 381a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch logout_button_->SetBorder(border.PassAs<views::Border>()); 382a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 383a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AddChildView(logout_button_); 384a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 385a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 386a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid UserView::AddUserCard(user::LoginStatus login) { 387a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Add padding around the panel. 388a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetBorder(views::Border::CreateEmptyBorder(kTrayPopupUserCardVerticalPadding, 389a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch kTrayPopupPaddingHorizontal, 390a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch kTrayPopupUserCardVerticalPadding, 391a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch kTrayPopupPaddingHorizontal)); 392a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 393a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::TrayBubbleView* bubble_view = 394a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch owner_->system_tray()->GetSystemBubble()->bubble_view(); 395a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int max_card_width = 396a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bubble_view->GetMaximumSize().width() - 397a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch (2 * kTrayPopupPaddingHorizontal + kTrayPopupPaddingBetweenItems); 398a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (logout_button_) 399a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch max_card_width -= logout_button_->GetPreferredSize().width(); 400a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch user_card_view_ = 401a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch new UserCardView(login, max_card_width, multiprofile_index_); 40203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // The entry is clickable when no system modal dialog is open and one of the 40303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // multi user options is active. 40403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool clickable = !Shell::GetInstance()->IsSystemModalWindowOpen() && 40503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) (IsMultiProfileSupportedAndUserActive() || 40603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) IsMultiAccountSupportedAndUserActive()); 407a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (clickable) { 408a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // To allow the border to start before the icon, reduce the size before and 409a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // add an inset to the icon to get the spacing. 410a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!multiprofile_index_) { 411a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetBorder(views::Border::CreateEmptyBorder( 412a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch kTrayPopupUserCardVerticalPadding, 413a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch kTrayPopupPaddingHorizontal - kTrayUserTileHoverBorderInset, 414a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch kTrayPopupUserCardVerticalPadding, 415a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch kTrayPopupPaddingHorizontal)); 416a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch user_card_view_->SetBorder(views::Border::CreateEmptyBorder( 417a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 0, kTrayUserTileHoverBorderInset, 0, 0)); 418a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gfx::Insets insets = gfx::Insets(1, 1, 1, 1); 420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch views::View* contents_view = user_card_view_; 421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ButtonFromView* button = NULL; 422a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!for_detailed_view_) { 423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (multiprofile_index_) { 424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Since the activation border needs to be drawn around the tile, we 425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // have to put the tile into another view which fills the menu panel, 426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // but keeping the offsets of the content. 427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch contents_view = new views::View(); 428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch contents_view->SetBorder(views::Border::CreateEmptyBorder( 429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kTrayPopupUserCardVerticalPadding, 430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kTrayPopupPaddingHorizontal, 431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kTrayPopupUserCardVerticalPadding, 432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kTrayPopupPaddingHorizontal)); 433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch contents_view->SetLayoutManager(new views::FillLayout()); 434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SetBorder(views::Border::CreateEmptyBorder(0, 0, 0, 0)); 435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch contents_view->AddChildView(user_card_view_); 436116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch insets = gfx::Insets(1, 1, 1, 3); 437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch button = new ButtonFromView(contents_view, 439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this, 440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch !multiprofile_index_, 441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch insets); 442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(skuhne): For accessibility we need to call |SetAccessibleName| 443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // with a useful name (string freeze for M37 has passed). 444a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else { 445a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // We want user card for detailed view to have exactly the same look 446a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // as user card for default view. That's why we wrap it in a button 447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // without click listener and special hover behavior. 448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch button = new ButtonFromView(contents_view, NULL, false, insets); 449a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // A click on the button should not trigger a focus change. 451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch button->set_request_focus_on_press(false); 452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch user_card_view_ = button; 453a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch is_user_card_button_ = true; 454a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 455a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AddChildViewAt(user_card_view_, 0); 4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Card for supervised user can consume more space than currently 457a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // available. In that case we should increase system bubble's width. 458a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (login == user::LOGGED_IN_PUBLIC) 459a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bubble_view->SetWidth(GetPreferredSize().width()); 460a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 461a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 462a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid UserView::ToggleAddUserMenuOption() { 463a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (add_menu_option_.get()) { 464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RemoveAddUserMenuOption(); 465a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 466a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 467a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 468a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Note: We do not need to install a global event handler to delete this 469a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // item since it will destroyed automatically before the menu / user menu item 470a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // gets destroyed.. 471a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_menu_option_.reset(new views::Widget); 472a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::Widget::InitParams params; 473a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch params.type = views::Widget::InitParams::TYPE_TOOLTIP; 474a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch params.keep_on_top = true; 475a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch params.context = this->GetWidget()->GetNativeWindow(); 476a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch params.accept_events = true; 477a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 478a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 479a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_menu_option_->Init(params); 480a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_menu_option_->SetOpacity(0xFF); 481a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_menu_option_->GetNativeWindow()->set_owned_by_parent(false); 482a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetShadowType(add_menu_option_->GetNativeView(), wm::SHADOW_TYPE_NONE); 483a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 484a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Position it below our user card. 485a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect bounds = user_card_view_->GetBoundsInScreen(); 486a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bounds.set_y(bounds.y() + bounds.height()); 487a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_menu_option_->SetBounds(bounds); 488a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 489a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Show the content. 490a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_menu_option_->SetAlwaysOnTop(true); 491a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_menu_option_->Show(); 492a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 493a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AddUserView* add_user_view = 494a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch new AddUserView(static_cast<ButtonFromView*>(user_card_view_)); 495a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 496a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const SessionStateDelegate* delegate = 497a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch Shell::GetInstance()->session_state_delegate(); 4986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SessionStateDelegate::AddUserError add_user_error; 5001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci add_user_enabled_ = delegate->CanAddUserToMultiProfile(&add_user_error); 5011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ButtonFromView* button = new ButtonFromView(add_user_view, 5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci add_user_enabled_ ? this : NULL, 5041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci add_user_enabled_, 5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Insets(1, 1, 1, 1)); 506116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch button->set_request_focus_on_press(false); 507116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch button->SetAccessibleName( 508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); 509a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch button->ForceBorderVisible(true); 510a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_menu_option_->SetContentsView(button); 511a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 5121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (add_user_enabled_) { 5131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // We activate the entry automatically if invoked with focus. 5141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (user_card_view_->HasFocus()) { 5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci button->GetFocusManager()->SetFocusedView(button); 5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci user_card_view_->GetFocusManager()->SetFocusedView(button); 5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 519a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); 5201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int message_id = 0; 5211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (add_user_error) { 5221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case SessionStateDelegate::ADD_USER_ERROR_NOT_ALLOWED_PRIMARY_USER: 5231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci message_id = IDS_ASH_STATUS_TRAY_MESSAGE_NOT_ALLOWED_PRIMARY_USER; 5241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 5251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case SessionStateDelegate::ADD_USER_ERROR_MAXIMUM_USERS_REACHED: 5261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci message_id = IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER; 5271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 5281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case SessionStateDelegate::ADD_USER_ERROR_OUT_OF_USERS: 5291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci message_id = IDS_ASH_STATUS_TRAY_MESSAGE_OUT_OF_USERS; 5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 5311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci default: 5321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED() << "Unknown adding user error " << add_user_error; 5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 5346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 535a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch popup_message_.reset(new PopupMessage( 536a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAPTION_CANNOT_ADD_USER), 5376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bundle.GetLocalizedString(message_id), 538a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PopupMessage::ICON_WARNING, 539a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch add_user_view->anchor(), 540a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::BubbleBorder::TOP_LEFT, 541a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Size(parent()->bounds().width() - kPopupMessageOffset, 0), 542a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 2 * kPopupMessageOffset)); 543a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 544a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Find the screen area which encloses both elements and sets then a mouse 545a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // watcher which will close the "menu". 546a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect area = user_card_view_->GetBoundsInScreen(); 547a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch area.set_height(2 * area.height()); 548a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch mouse_watcher_.reset( 549a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch new views::MouseWatcher(new UserViewMouseWatcherHost(area), this)); 550a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch mouse_watcher_->Start(); 551116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Install a listener to focus changes so that we can remove the card when 552116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the focus gets changed. When called through the destruction of the bubble, 553116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the FocusManager cannot be determined anymore and we remember it here. 554116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch focus_manager_ = user_card_view_->GetFocusManager(); 555116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch focus_manager_->AddFocusChangeListener(this); 556116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 557116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 558116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid UserView::RemoveAddUserMenuOption() { 559116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!add_menu_option_.get()) 560116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 561116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch focus_manager_->RemoveFocusChangeListener(this); 562116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch focus_manager_ = NULL; 563116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (user_card_view_->GetFocusManager()) 564116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch user_card_view_->GetFocusManager()->ClearFocus(); 565116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch popup_message_.reset(); 566116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch mouse_watcher_.reset(); 567116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch add_menu_option_.reset(); 568a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 569a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 570a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} // namespace tray 571a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} // namespace ash 572