OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/system/user/tray_user.h" | 5 #include "ash/system/user/tray_user.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <climits> | 8 #include <climits> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "ash/popup_message.h" | |
11 #include "ash/session_state_delegate.h" | 12 #include "ash/session_state_delegate.h" |
12 #include "ash/shell.h" | 13 #include "ash/shell.h" |
13 #include "ash/shell_delegate.h" | 14 #include "ash/shell_delegate.h" |
14 #include "ash/system/tray/system_tray.h" | 15 #include "ash/system/tray/system_tray.h" |
15 #include "ash/system/tray/system_tray_delegate.h" | 16 #include "ash/system/tray/system_tray_delegate.h" |
16 #include "ash/system/tray/system_tray_notifier.h" | 17 #include "ash/system/tray/system_tray_notifier.h" |
17 #include "ash/system/tray/tray_constants.h" | 18 #include "ash/system/tray/tray_constants.h" |
18 #include "ash/system/tray/tray_item_view.h" | 19 #include "ash/system/tray/tray_item_view.h" |
19 #include "ash/system/tray/tray_popup_label_button.h" | 20 #include "ash/system/tray/tray_popup_label_button.h" |
20 #include "ash/system/tray/tray_popup_label_button_border.h" | 21 #include "ash/system/tray/tray_popup_label_button_border.h" |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
98 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | 99 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, |
99 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | 100 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, |
100 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | 101 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, |
101 IDR_AURA_TRAY_POPUP_LABEL_BUTTON_HOVER_BACKGROUND, | 102 IDR_AURA_TRAY_POPUP_LABEL_BUTTON_HOVER_BACKGROUND, |
102 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | 103 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, |
103 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | 104 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, |
104 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | 105 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, |
105 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, | 106 IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER, |
106 }; | 107 }; |
107 | 108 |
109 // Offsetting the popup message relativ to the tray menu. | |
Nikita (slow)
2013/05/21 18:03:52
nit: relative
Mr4D (OOO till 08-26)
2013/05/21 19:23:33
Done.
| |
110 const int kPopupMessageOffset = 25; | |
111 | |
108 } // namespace | 112 } // namespace |
109 | 113 |
110 namespace ash { | 114 namespace ash { |
111 namespace internal { | 115 namespace internal { |
112 | 116 |
113 namespace tray { | 117 namespace tray { |
114 | 118 |
115 // A custom image view with rounded edges. | 119 // A custom image view with rounded edges. |
116 class RoundedImageView : public views::View { | 120 class RoundedImageView : public views::View { |
117 public: | 121 public: |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
255 // Create the additional user card content for the public mode. | 259 // Create the additional user card content for the public mode. |
256 void AddLoggedInPublicModeUserCardContent(SystemTrayItem* owner); | 260 void AddLoggedInPublicModeUserCardContent(SystemTrayItem* owner); |
257 | 261 |
258 // Create the menu option to add another user. If |disabled| is set the user | 262 // Create the menu option to add another user. If |disabled| is set the user |
259 // cannot actively click on the item. | 263 // cannot actively click on the item. |
260 void ToggleAddUserMenuOption(); | 264 void ToggleAddUserMenuOption(); |
261 | 265 |
262 MultiProfileIndex multiprofile_index_; | 266 MultiProfileIndex multiprofile_index_; |
263 views::View* user_card_; | 267 views::View* user_card_; |
264 views::View* logout_button_; | 268 views::View* logout_button_; |
269 scoped_ptr<ash::PopupMessage> popup_message_; | |
265 scoped_ptr<views::Widget> add_menu_option_; | 270 scoped_ptr<views::Widget> add_menu_option_; |
266 | 271 |
267 // The mouse watcher which takes care of out of window hover events. | 272 // The mouse watcher which takes care of out of window hover events. |
268 scoped_ptr<views::MouseWatcher> mouse_watcher_; | 273 scoped_ptr<views::MouseWatcher> mouse_watcher_; |
269 | 274 |
270 DISALLOW_COPY_AND_ASSIGN(UserView); | 275 DISALLOW_COPY_AND_ASSIGN(UserView); |
271 }; | 276 }; |
272 | 277 |
273 // The menu item view which gets shown when the user clicks in multi profile | 278 // The menu item view which gets shown when the user clicks in multi profile |
274 // mode onto the user item. | 279 // mode onto the user item. |
275 class AddUserView : public views::CustomButton, | 280 class AddUserView : public views::CustomButton, |
276 public views::ButtonListener { | 281 public views::ButtonListener { |
277 public: | 282 public: |
278 // The |owner| is the view for which this view gets created. The |listener| | 283 // The |owner| is the view for which this view gets created. The |listener| |
279 // will get notified when this item gets clicked. | 284 // will get notified when this item gets clicked. |
280 AddUserView(UserCard* owner, views::ButtonListener* listener); | 285 AddUserView(UserCard* owner, views::ButtonListener* listener); |
281 virtual ~AddUserView(); | 286 virtual ~AddUserView(); |
282 | 287 |
288 // Get the anchor view for a message. | |
289 views::View* anchor() { return anchor_; } | |
290 | |
283 // Overridden from views::ButtonListener. | 291 // Overridden from views::ButtonListener. |
284 virtual void ButtonPressed(views::Button* sender, | 292 virtual void ButtonPressed(views::Button* sender, |
285 const ui::Event& event) OVERRIDE; | 293 const ui::Event& event) OVERRIDE; |
286 | 294 |
287 private: | 295 private: |
288 // Overridden from views::View. | 296 // Overridden from views::View. |
289 virtual gfx::Size GetPreferredSize() OVERRIDE; | 297 virtual gfx::Size GetPreferredSize() OVERRIDE; |
290 virtual int GetHeightForWidth(int width) OVERRIDE; | 298 virtual int GetHeightForWidth(int width) OVERRIDE; |
291 virtual void Layout() OVERRIDE; | 299 virtual void Layout() OVERRIDE; |
292 | 300 |
293 // Create the additional client content for this item. | 301 // Create the additional client content for this item. |
294 void AddContent(); | 302 void AddContent(); |
295 | 303 |
296 // This is the content we create and show. | 304 // This is the content we create and show. |
297 views::View* add_user_; | 305 views::View* add_user_; |
298 | 306 |
299 // This listener will get informed when someone clicks on this button. | 307 // This listener will get informed when someone clicks on this button. |
300 views::ButtonListener* listener_; | 308 views::ButtonListener* listener_; |
301 | 309 |
302 // This is the owner view of this item. | 310 // This is the owner view of this item. |
303 UserCard* owner_; | 311 UserCard* owner_; |
304 | 312 |
313 // The anchor view for the "all users are already assigned" message. | |
Nikita (slow)
2013/05/21 18:03:52
nit: I would leave comment more generic as it coul
Mr4D (OOO till 08-26)
2013/05/21 19:23:33
Good point. Done.
| |
314 views::View* anchor_; | |
315 | |
305 DISALLOW_COPY_AND_ASSIGN(AddUserView); | 316 DISALLOW_COPY_AND_ASSIGN(AddUserView); |
306 }; | 317 }; |
307 | 318 |
308 RoundedImageView::RoundedImageView(int corner_radius, bool active_user) | 319 RoundedImageView::RoundedImageView(int corner_radius, bool active_user) |
309 : corner_radius_(corner_radius), | 320 : corner_radius_(corner_radius), |
310 active_user_(active_user) {} | 321 active_user_(active_user) {} |
311 | 322 |
312 RoundedImageView::~RoundedImageView() {} | 323 RoundedImageView::~RoundedImageView() {} |
313 | 324 |
314 void RoundedImageView::SetImage(const gfx::ImageSkia& img, | 325 void RoundedImageView::SetImage(const gfx::ImageSkia& img, |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
584 // The logout button must be added before the user card so that the user card | 595 // The logout button must be added before the user card so that the user card |
585 // can correctly calculate the remaining available width. | 596 // can correctly calculate the remaining available width. |
586 // Note that only the current multiprofile user gets a button. | 597 // Note that only the current multiprofile user gets a button. |
587 AddLogoutButton(!multiprofile_index_ ? login : ash::user::LOGGED_IN_LOCKED); | 598 AddLogoutButton(!multiprofile_index_ ? login : ash::user::LOGGED_IN_LOCKED); |
588 AddUserCard(owner, login); | 599 AddUserCard(owner, login); |
589 } | 600 } |
590 | 601 |
591 UserView::~UserView() {} | 602 UserView::~UserView() {} |
592 | 603 |
593 void UserView::MouseMovedOutOfHost() { | 604 void UserView::MouseMovedOutOfHost() { |
594 // Make sure that the MouseWatcher does not outlive our add menu option. | 605 popup_message_.reset(); |
595 DCHECK(!add_menu_option_.get()); | |
596 mouse_watcher_.reset(); | 606 mouse_watcher_.reset(); |
597 add_menu_option_.reset(); | 607 add_menu_option_.reset(); |
598 } | 608 } |
599 | 609 |
600 gfx::Size UserView::GetPreferredSize() { | 610 gfx::Size UserView::GetPreferredSize() { |
601 gfx::Size size = views::View::GetPreferredSize(); | 611 gfx::Size size = views::View::GetPreferredSize(); |
602 // Only the active user panel will be forced to a certain height. | 612 // Only the active user panel will be forced to a certain height. |
603 if (!multiprofile_index_) { | 613 if (!multiprofile_index_) { |
604 size.set_height(std::max(size.height(), | 614 size.set_height(std::max(size.height(), |
605 kTrayPopupItemHeight + GetInsets().height())); | 615 kTrayPopupItemHeight + GetInsets().height())); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
825 } | 835 } |
826 | 836 |
827 void UserView::AddLoggedInPublicModeUserCardContent(SystemTrayItem* owner) { | 837 void UserView::AddLoggedInPublicModeUserCardContent(SystemTrayItem* owner) { |
828 user_card_->AddChildView(CreateIconForUserCard(ash::user::LOGGED_IN_PUBLIC)); | 838 user_card_->AddChildView(CreateIconForUserCard(ash::user::LOGGED_IN_PUBLIC)); |
829 user_card_->AddChildView(new PublicAccountUserDetails( | 839 user_card_->AddChildView(new PublicAccountUserDetails( |
830 owner, GetPreferredSize().width() + kTrayPopupPaddingBetweenItems)); | 840 owner, GetPreferredSize().width() + kTrayPopupPaddingBetweenItems)); |
831 } | 841 } |
832 | 842 |
833 void UserView::ToggleAddUserMenuOption() { | 843 void UserView::ToggleAddUserMenuOption() { |
834 if (add_menu_option_.get()) { | 844 if (add_menu_option_.get()) { |
845 popup_message_.reset(); | |
835 mouse_watcher_.reset(); | 846 mouse_watcher_.reset(); |
836 add_menu_option_.reset(); | 847 add_menu_option_.reset(); |
837 return; | 848 return; |
838 } | 849 } |
839 | 850 |
840 // Note: We do not need to install a global event handler to delete this | 851 // Note: We do not need to install a global event handler to delete this |
841 // item since it will destroyed automatically before the menu / user menu item | 852 // item since it will destroyed automatically before the menu / user menu item |
842 // gets destroyed.. | 853 // gets destroyed.. |
843 const SessionStateDelegate* session_state_delegate = | 854 const SessionStateDelegate* session_state_delegate = |
844 ash::Shell::GetInstance()->session_state_delegate(); | 855 ash::Shell::GetInstance()->session_state_delegate(); |
(...skipping 13 matching lines...) Expand all Loading... | |
858 add_menu_option_->GetNativeWindow()->set_owned_by_parent(false); | 869 add_menu_option_->GetNativeWindow()->set_owned_by_parent(false); |
859 SetShadowType(add_menu_option_->GetNativeView(), | 870 SetShadowType(add_menu_option_->GetNativeView(), |
860 views::corewm::SHADOW_TYPE_NONE); | 871 views::corewm::SHADOW_TYPE_NONE); |
861 | 872 |
862 // Position it below our user card. | 873 // Position it below our user card. |
863 gfx::Rect bounds = user_card_->GetBoundsInScreen(); | 874 gfx::Rect bounds = user_card_->GetBoundsInScreen(); |
864 bounds.set_y(bounds.y() + bounds.height()); | 875 bounds.set_y(bounds.y() + bounds.height()); |
865 add_menu_option_->SetBounds(bounds); | 876 add_menu_option_->SetBounds(bounds); |
866 | 877 |
867 // Show the content. | 878 // Show the content. |
868 add_menu_option_->SetContentsView(new AddUserView( | 879 AddUserView* add_user_view = new AddUserView( |
869 static_cast<UserCard*>(user_card_), this)); | 880 static_cast<UserCard*>(user_card_), this); |
881 add_menu_option_->SetContentsView(add_user_view); | |
870 add_menu_option_->SetAlwaysOnTop(true); | 882 add_menu_option_->SetAlwaysOnTop(true); |
871 add_menu_option_->Show(); | 883 add_menu_option_->Show(); |
872 if (cannot_add_more_users) { | 884 if (cannot_add_more_users) { |
873 // TODO(skuhne): Use IDS_ASH_STATUS_TRAY_CAPTION_CANNOT_ADD_USER and | 885 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
874 // IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER when showing the error | 886 popup_message_.reset(new PopupMessage( |
875 // message that no more users can be added. | 887 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAPTION_CANNOT_ADD_USER), |
888 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER), | |
889 PopupMessage::ICON_WARNING, | |
890 add_user_view->anchor(), | |
891 views::BubbleBorder::TOP_LEFT, | |
892 gfx::Size(parent()->bounds().width() - kPopupMessageOffset, 0), | |
893 2 * kPopupMessageOffset)); | |
876 } | 894 } |
877 // Find the screen area which encloses both elements and sets then a mouse | 895 // Find the screen area which encloses both elements and sets then a mouse |
878 // watcher which will close the "menu". | 896 // watcher which will close the "menu". |
879 gfx::Rect area = user_card_->GetBoundsInScreen(); | 897 gfx::Rect area = user_card_->GetBoundsInScreen(); |
880 area.set_height(2 * area.height()); | 898 area.set_height(2 * area.height()); |
881 mouse_watcher_.reset(new views::MouseWatcher( | 899 mouse_watcher_.reset(new views::MouseWatcher( |
882 new UserViewMouseWatcherHost(area), | 900 new UserViewMouseWatcherHost(area), |
883 this)); | 901 this)); |
884 mouse_watcher_->Start(); | 902 mouse_watcher_->Start(); |
885 } | 903 } |
886 | 904 |
887 AddUserView::AddUserView(UserCard* owner, views::ButtonListener* listener) | 905 AddUserView::AddUserView(UserCard* owner, views::ButtonListener* listener) |
888 : CustomButton(listener_), | 906 : CustomButton(listener_), |
889 add_user_(NULL), | 907 add_user_(NULL), |
890 listener_(listener), | 908 listener_(listener), |
891 owner_(owner) { | 909 owner_(owner), |
910 anchor_(NULL) { | |
892 AddContent(); | 911 AddContent(); |
893 owner_->ForceBorderVisible(true); | 912 owner_->ForceBorderVisible(true); |
894 } | 913 } |
895 | 914 |
896 AddUserView::~AddUserView() { | 915 AddUserView::~AddUserView() { |
897 owner_->ForceBorderVisible(false); | 916 owner_->ForceBorderVisible(false); |
898 } | 917 } |
899 | 918 |
900 gfx::Size AddUserView::GetPreferredSize() { | 919 gfx::Size AddUserView::GetPreferredSize() { |
901 return owner_->bounds().size(); | 920 return owner_->bounds().size(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
935 add_user_->set_border(views::Border::CreateEmptyBorder( | 954 add_user_->set_border(views::Border::CreateEmptyBorder( |
936 kUserCardVerticalPadding, | 955 kUserCardVerticalPadding, |
937 kTrayPopupPaddingHorizontal- kTrayUserTileHoverBorderInset, | 956 kTrayPopupPaddingHorizontal- kTrayUserTileHoverBorderInset, |
938 kUserCardVerticalPadding, | 957 kUserCardVerticalPadding, |
939 kTrayPopupPaddingHorizontal- kTrayUserTileHoverBorderInset)); | 958 kTrayPopupPaddingHorizontal- kTrayUserTileHoverBorderInset)); |
940 | 959 |
941 add_user_->SetLayoutManager(new views::BoxLayout( | 960 add_user_->SetLayoutManager(new views::BoxLayout( |
942 views::BoxLayout::kHorizontal, 0, 0 , kTrayPopupPaddingBetweenItems)); | 961 views::BoxLayout::kHorizontal, 0, 0 , kTrayPopupPaddingBetweenItems)); |
943 AddChildViewAt(add_user_, 0); | 962 AddChildViewAt(add_user_, 0); |
944 | 963 |
945 // Add the [+] icon. | 964 // Add the [+] icon which is also the anchor for messages. |
946 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | 965 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
947 RoundedImageView* icon = new RoundedImageView(kProfileRoundedCornerRadius, | 966 RoundedImageView* icon = new RoundedImageView(kProfileRoundedCornerRadius, |
948 true); | 967 true); |
949 // TODO(skuhne): Add the resource and load the proper icon. | 968 anchor_ = icon; |
950 icon->SetImage(*ui::ResourceBundle::GetSharedInstance(). | 969 icon->SetImage(*ui::ResourceBundle::GetSharedInstance(). |
951 GetImageNamed(IDR_AURA_UBER_TRAY_GUEST_ICON).ToImageSkia(), | 970 GetImageNamed(IDR_AURA_UBER_TRAY_ADD_MULTIPROFILE_USER).ToImageSkia(), |
952 gfx::Size(kUserIconSize, kUserIconSize)); | 971 gfx::Size(kUserIconSize, kUserIconSize)); |
953 add_user_->AddChildView(icon); | 972 add_user_->AddChildView(icon); |
954 | 973 |
955 // Add the command text. | 974 // Add the command text. |
956 views::Label* command_label = new views::Label( | 975 views::Label* command_label = new views::Label( |
957 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); | 976 bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT)); |
958 command_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 977 command_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
959 add_user_->AddChildView(command_label); | 978 add_user_->AddChildView(command_label); |
960 } | 979 } |
961 | 980 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1003 // If there are multiple users logged in, the users will be separated from the | 1022 // If there are multiple users logged in, the users will be separated from the |
1004 // rest of the menu by a separator. | 1023 // rest of the menu by a separator. |
1005 if (multiprofile_index_ == | 1024 if (multiprofile_index_ == |
1006 session_state_delegate->GetMaximumNumberOfLoggedInUsers() && | 1025 session_state_delegate->GetMaximumNumberOfLoggedInUsers() && |
1007 logged_in_users > 1) { | 1026 logged_in_users > 1) { |
1008 return new views::View(); | 1027 return new views::View(); |
1009 } | 1028 } |
1010 | 1029 |
1011 // Do not show more UserView's then there are logged in users. | 1030 // Do not show more UserView's then there are logged in users. |
1012 if (multiprofile_index_ >= logged_in_users) | 1031 if (multiprofile_index_ >= logged_in_users) |
1013 return NULL;; | 1032 return NULL; |
1014 | 1033 |
1015 user_ = new tray::UserView(this, status, multiprofile_index_); | 1034 user_ = new tray::UserView(this, status, multiprofile_index_); |
1016 return user_; | 1035 return user_; |
1017 } | 1036 } |
1018 | 1037 |
1019 views::View* TrayUser::CreateDetailedView(user::LoginStatus status) { | 1038 views::View* TrayUser::CreateDetailedView(user::LoginStatus status) { |
1020 return NULL; | 1039 return NULL; |
1021 } | 1040 } |
1022 | 1041 |
1023 void TrayUser::DestroyTrayView() { | 1042 void TrayUser::DestroyTrayView() { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1138 if (avatar_) { | 1157 if (avatar_) { |
1139 avatar_->SetImage( | 1158 avatar_->SetImage( |
1140 ash::Shell::GetInstance()->session_state_delegate()->GetUserImage( | 1159 ash::Shell::GetInstance()->session_state_delegate()->GetUserImage( |
1141 multiprofile_index_), | 1160 multiprofile_index_), |
1142 gfx::Size(kUserIconSize, kUserIconSize)); | 1161 gfx::Size(kUserIconSize, kUserIconSize)); |
1143 } | 1162 } |
1144 } | 1163 } |
1145 | 1164 |
1146 } // namespace internal | 1165 } // namespace internal |
1147 } // namespace ash | 1166 } // namespace ash |
OLD | NEW |