Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: chrome/browser/ui/views/profile_chooser_view.cc

Issue 143743005: [Mac, Win] New avatar bubble should be a fixed width. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "chrome/browser/ui/views/profile_chooser_view.h" 5 #include "chrome/browser/ui/views/profile_chooser_view.h"
6 6
7 #include "base/strings/utf_string_conversions.h" 7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/browser_process.h" 8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/profiles/profile_info_util.h" 9 #include "chrome/browser/profiles/profile_info_util.h"
10 #include "chrome/browser/profiles/profile_manager.h" 10 #include "chrome/browser/profiles/profile_manager.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 #include "ui/views/widget/widget.h" 42 #include "ui/views/widget/widget.h"
43 43
44 #if defined(USE_AURA) 44 #if defined(USE_AURA)
45 #include "ui/native_theme/native_theme_aura.h" 45 #include "ui/native_theme/native_theme_aura.h"
46 #endif 46 #endif
47 47
48 namespace { 48 namespace {
49 49
50 // Helpers -------------------------------------------------------------------- 50 // Helpers --------------------------------------------------------------------
51 51
52 const int kMinMenuWidth = 250; 52 const int kFixedMenuWidth = 250;
53 const int kButtonHeight = 29; 53 const int kButtonHeight = 29;
54 const int kLargeImageSide = 64;
54 55
55 // Creates a GridLayout with a single column. This ensures that all the child 56 // Creates a GridLayout with a single column. This ensures that all the child
56 // views added get auto-expanded to fill the full width of the bubble. 57 // views added get auto-expanded to fill the full width of the bubble.
57 views::GridLayout* CreateSingleColumnLayout(views::View* view) { 58 views::GridLayout* CreateSingleColumnLayout(views::View* view) {
58 views::GridLayout* layout = new views::GridLayout(view); 59 views::GridLayout* layout = new views::GridLayout(view);
59 view->SetLayoutManager(layout); 60 view->SetLayoutManager(layout);
60 61
61 views::ColumnSet* columns = layout->AddColumnSet(0); 62 views::ColumnSet* columns = layout->AddColumnSet(0);
62 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, 63 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
63 views::GridLayout::USE_PREF, 0, 0); 64 views::GridLayout::FIXED, kFixedMenuWidth, 0);
64 return layout; 65 return layout;
65 } 66 }
66 67
67 // Creates a GridLayout with two columns. 68 // Creates a GridLayout with two columns.
68 views::GridLayout* CreateDoubleColumnLayout(views::View* view) { 69 views::GridLayout* CreateDoubleColumnLayout(views::View* view) {
69 views::GridLayout* layout = new views::GridLayout(view); 70 views::GridLayout* layout = new views::GridLayout(view);
70 view->SetLayoutManager(layout); 71 view->SetLayoutManager(layout);
71 72
72 views::ColumnSet* columns = layout->AddColumnSet(0); 73 views::ColumnSet* columns = layout->AddColumnSet(0);
73 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0, 74 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0,
74 views::GridLayout::USE_PREF, 0, 0); 75 views::GridLayout::USE_PREF, 0, 0);
75 columns->AddPaddingColumn(0, views::kUnrelatedControlLargeHorizontalSpacing); 76 columns->AddPaddingColumn(0, views::kUnrelatedControlLargeHorizontalSpacing);
76 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0, 77 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
77 views::GridLayout::USE_PREF, 0, 0); 78 views::GridLayout::USE_PREF, 0, 0);
78 return layout; 79 return layout;
79 } 80 }
80 81
81 views::Link* CreateLink(const base::string16& link_text, 82 views::Link* CreateLink(const base::string16& link_text,
82 views::LinkListener* listener) { 83 views::LinkListener* listener) {
83 views::Link* link_button = new views::Link(link_text); 84 views::Link* link_button = new views::Link(link_text);
84 link_button->SetHorizontalAlignment(gfx::ALIGN_LEFT); 85 link_button->SetHorizontalAlignment(gfx::ALIGN_LEFT);
85 link_button->SetUnderline(false); 86 link_button->SetUnderline(false);
86 link_button->set_listener(listener); 87 link_button->set_listener(listener);
87 return link_button; 88 return link_button;
88 } 89 }
89 90
91 base::string16 ElideText(const base::string16& text,
92 float width,
93 ui::ResourceBundle::FontStyle font_style) {
94 return gfx::ElideText(
95 text,
96 ui::ResourceBundle::GetSharedInstance().GetFontList(font_style),
97 width,
98 gfx::ELIDE_AT_END);
99 }
100
90 101
91 // BackgroundColorHoverButton ------------------------------------------------- 102 // BackgroundColorHoverButton -------------------------------------------------
92 103
93 // A custom button that allows for setting a background color when hovered over. 104 // A custom button that allows for setting a background color when hovered over.
94 class BackgroundColorHoverButton : public views::TextButton { 105 class BackgroundColorHoverButton : public views::TextButton {
95 public: 106 public:
96 BackgroundColorHoverButton(views::ButtonListener* listener, 107 BackgroundColorHoverButton(views::ButtonListener* listener,
97 const base::string16& text, 108 const base::string16& text,
98 const gfx::ImageSkia& normal_icon, 109 const gfx::ImageSkia& normal_icon,
99 const gfx::ImageSkia& hover_icon); 110 const gfx::ImageSkia& hover_icon);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 // EditableProfilePhoto ------------------------------------------------- 170 // EditableProfilePhoto -------------------------------------------------
160 171
161 // A custom Image control that shows a "change" button when moused over. 172 // A custom Image control that shows a "change" button when moused over.
162 class EditableProfilePhoto : public views::ImageView { 173 class EditableProfilePhoto : public views::ImageView {
163 public: 174 public:
164 EditableProfilePhoto(views::ButtonListener* listener, 175 EditableProfilePhoto(views::ButtonListener* listener,
165 const gfx::Image& icon, 176 const gfx::Image& icon,
166 bool is_editing_allowed) 177 bool is_editing_allowed)
167 : views::ImageView(), 178 : views::ImageView(),
168 change_photo_button_(NULL) { 179 change_photo_button_(NULL) {
169 const int kLargeImageSide = 64;
170 const SkColor kBackgroundColor = SkColorSetARGB(125, 0, 0, 0); 180 const SkColor kBackgroundColor = SkColorSetARGB(125, 0, 0, 0);
171 const int kOverlayHeight = 20; 181 const int kOverlayHeight = 20;
172 182
173 gfx::Image image = profiles::GetSizedAvatarIconWithBorder( 183 gfx::Image image = profiles::GetSizedAvatarIconWithBorder(
174 icon, true, 184 icon, true,
175 kLargeImageSide + profiles::kAvatarIconPadding, 185 kLargeImageSide + profiles::kAvatarIconPadding,
176 kLargeImageSide + profiles::kAvatarIconPadding); 186 kLargeImageSide + profiles::kAvatarIconPadding);
177 SetImage(image.ToImageSkia()); 187 SetImage(image.ToImageSkia());
178 188
179 if (!is_editing_allowed) 189 if (!is_editing_allowed)
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 237
228 // EditableProfileName ------------------------------------------------- 238 // EditableProfileName -------------------------------------------------
229 239
230 // A custom text control that turns into a textfield for editing when clicked. 240 // A custom text control that turns into a textfield for editing when clicked.
231 class EditableProfileName : public views::TextButton, 241 class EditableProfileName : public views::TextButton,
232 public views::ButtonListener { 242 public views::ButtonListener {
233 public: 243 public:
234 EditableProfileName(views::TextfieldController* controller, 244 EditableProfileName(views::TextfieldController* controller,
235 const base::string16& text, 245 const base::string16& text,
236 bool is_editing_allowed) 246 bool is_editing_allowed)
237 : views::TextButton(this, text), 247 : views::TextButton(this, base::string16()),
248 full_profile_name_(text),
238 profile_name_textfield_(NULL) { 249 profile_name_textfield_(NULL) {
250
251 // The button has a fixed width, so we need to calculate the exact width
252 // available for the profile name column, so that the text can be
253 // elided correctly if needed.
254 float available_button_width =
255 kFixedMenuWidth - // Entire width of the bubble.
256 2 * views::kButtonHEdgeMarginNew - // Bubble insets.
257 kLargeImageSide - // Width of the profile photo.
258 views::kUnrelatedControlLargeHorizontalSpacing;
259
239 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 260 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
261 const gfx::ImageSkia& icon = *rb->GetImageSkiaNamed(IDR_INFOBAR_AUTOFILL);
262 float icon_width = is_editing_allowed? icon.width() : 0;
263 base::string16 elided_name = ElideText(text,
sky 2014/01/23 01:00:52 You shouldn't need to elide the text yourself. You
264 available_button_width - icon_width,
265 ui::ResourceBundle::MediumFont);
240 const gfx::FontList& medium_font_list = 266 const gfx::FontList& medium_font_list =
241 rb->GetFontList(ui::ResourceBundle::MediumFont); 267 rb->GetFontList(ui::ResourceBundle::MediumFont);
242 SetFontList(medium_font_list); 268 SetFontList(medium_font_list);
269 SetText(elided_name);
243 set_border(NULL); 270 set_border(NULL);
244 271
245 if (!is_editing_allowed) 272 if (!is_editing_allowed)
246 return; 273 return;
247 274
248 SetIcon(*rb->GetImageSkiaNamed(IDR_INFOBAR_AUTOFILL)); 275 SetIcon(*rb->GetImageSkiaNamed(IDR_INFOBAR_AUTOFILL));
249 set_icon_placement(views::TextButton::ICON_ON_RIGHT); 276 set_icon_placement(views::TextButton::ICON_ON_RIGHT);
250 277
251 // Textfield that overlaps the button. 278 // Textfield that overlaps the button.
252 profile_name_textfield_ = new views::Textfield(); 279 profile_name_textfield_ = new views::Textfield();
(...skipping 13 matching lines...) Expand all
266 if (profile_name_textfield_) 293 if (profile_name_textfield_)
267 profile_name_textfield_->SetVisible(false); 294 profile_name_textfield_->SetVisible(false);
268 } 295 }
269 296
270 private: 297 private:
271 // views::ButtonListener: 298 // views::ButtonListener:
272 virtual void ButtonPressed(views::Button* sender, 299 virtual void ButtonPressed(views::Button* sender,
273 const ui::Event& event) OVERRIDE { 300 const ui::Event& event) OVERRIDE {
274 if (profile_name_textfield_) { 301 if (profile_name_textfield_) {
275 profile_name_textfield_->SetVisible(true); 302 profile_name_textfield_->SetVisible(true);
276 profile_name_textfield_->SetText(text()); 303 profile_name_textfield_->SetText(full_profile_name_);
277 profile_name_textfield_->SelectAll(false); 304 profile_name_textfield_->SelectAll(false);
278 profile_name_textfield_->RequestFocus(); 305 profile_name_textfield_->RequestFocus();
279 } 306 }
280 } 307 }
281 308
282 // views::CustomButton: 309 // views::CustomButton:
283 virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE { 310 virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE {
284 // Override CustomButton's implementation, which presses the button when 311 // Override CustomButton's implementation, which presses the button when
285 // you press space and clicks it when you release space, as the space can be 312 // you press space and clicks it when you release space, as the space can be
286 // part of the new profile name typed in the textfield. 313 // part of the new profile name typed in the textfield.
287 return false; 314 return false;
288 } 315 }
289 316
290 // views::View: 317 // views::View:
291 virtual void Layout() OVERRIDE { 318 virtual void Layout() OVERRIDE {
292 if (profile_name_textfield_) 319 if (profile_name_textfield_)
293 profile_name_textfield_->SetBounds(0, 0, width(), height()); 320 profile_name_textfield_->SetBounds(0, 0, width(), height());
294 views::View::Layout(); 321 views::View::Layout();
295 } 322 }
296 323
324 // The complete profile name. Because the control has a fixed width, we will
325 // have to elide the profile name when displaying it. However, in edit mode,
326 // we should show the entire name.
327 base::string16 full_profile_name_;
328
297 // Button that is shown when hovering over the image view. Can be NULL if 329 // Button that is shown when hovering over the image view. Can be NULL if
298 // the profile name isn't allowed to be edited (e.g. for guest profiles). 330 // the profile name isn't allowed to be edited (e.g. for guest profiles).
299 views::Textfield* profile_name_textfield_; 331 views::Textfield* profile_name_textfield_;
300 332
301 DISALLOW_COPY_AND_ASSIGN(EditableProfileName); 333 DISALLOW_COPY_AND_ASSIGN(EditableProfileName);
302 }; 334 };
303 335
304 336
305 // ProfileChooserView --------------------------------------------------------- 337 // ProfileChooserView ---------------------------------------------------------
306 338
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 const AvatarMenu::Item& active_item = avatar_menu->GetItemAt( 455 const AvatarMenu::Item& active_item = avatar_menu->GetItemAt(
424 avatar_menu->GetActiveProfileIndex()); 456 avatar_menu->GetActiveProfileIndex());
425 DCHECK(active_item.signed_in); 457 DCHECK(active_item.signed_in);
426 } 458 }
427 459
428 ResetView(); 460 ResetView();
429 RemoveAllChildViews(true); 461 RemoveAllChildViews(true);
430 view_mode_ = view_to_display; 462 view_mode_ = view_to_display;
431 463
432 views::GridLayout* layout = CreateSingleColumnLayout(this); 464 views::GridLayout* layout = CreateSingleColumnLayout(this);
433 layout->set_minimum_size(gfx::Size(kMinMenuWidth, 0)); 465 layout->set_minimum_size(gfx::Size(kFixedMenuWidth, 0));
434 466
435 if (view_to_display == GAIA_SIGNIN_VIEW || 467 if (view_to_display == GAIA_SIGNIN_VIEW ||
436 view_to_display == GAIA_ADD_ACCOUNT_VIEW) { 468 view_to_display == GAIA_ADD_ACCOUNT_VIEW) {
437 // Minimum size for embedded sign in pages as defined in Gaia. 469 // Minimum size for embedded sign in pages as defined in Gaia.
438 const int kMinGaiaViewWidth = 320; 470 const int kMinGaiaViewWidth = 320;
439 const int kMinGaiaViewHeight = 440; 471 const int kMinGaiaViewHeight = 440;
440 Profile* profile = browser_->profile(); 472 Profile* profile = browser_->profile();
441 views::WebView* web_view = new views::WebView(profile); 473 views::WebView* web_view = new views::WebView(profile);
442 signin::Source source = (view_to_display == GAIA_SIGNIN_VIEW) ? 474 signin::Source source = (view_to_display == GAIA_SIGNIN_VIEW) ?
443 signin::SOURCE_AVATAR_BUBBLE_SIGN_IN : 475 signin::SOURCE_AVATAR_BUBBLE_SIGN_IN :
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 for (int i = 0; i < num_avatars_to_show; ++i) { 739 for (int i = 0; i < num_avatars_to_show; ++i) {
708 const size_t index = avatars_to_show[i]; 740 const size_t index = avatars_to_show[i];
709 const AvatarMenu::Item& item = avatar_menu_->GetItemAt(index); 741 const AvatarMenu::Item& item = avatar_menu_->GetItemAt(index);
710 const int kSmallImageSide = 32; 742 const int kSmallImageSide = 32;
711 743
712 gfx::Image image = profiles::GetSizedAvatarIconWithBorder( 744 gfx::Image image = profiles::GetSizedAvatarIconWithBorder(
713 item.icon, true, 745 item.icon, true,
714 kSmallImageSide + profiles::kAvatarIconPadding, 746 kSmallImageSide + profiles::kAvatarIconPadding,
715 kSmallImageSide + profiles::kAvatarIconPadding); 747 kSmallImageSide + profiles::kAvatarIconPadding);
716 748
717 views::TextButton* button = new views::TextButton(this, item.name); 749 // Since the bubble has a fixed width, we need to calculate the exact
750 // width available for the profile name, and elide it if needed.
751 float available_text_width =
752 kFixedMenuWidth - // Entire width of the bubble.
753 2 * views::kButtonHEdgeMarginNew - // Insets.
754 kSmallImageSide - // Width of the button icon.
755 views::kItemLabelSpacing; // Space between text and icon.
756 views::TextButton* button = new views::TextButton(
757 this,
758 ElideText(item.name,
759 available_text_width,
760 ui::ResourceBundle::MediumFont));
718 open_other_profile_indexes_map_[button] = index; 761 open_other_profile_indexes_map_[button] = index;
719 button->SetIcon(*image.ToImageSkia()); 762 button->SetIcon(*image.ToImageSkia());
720 button->set_icon_text_spacing(views::kItemLabelSpacing); 763 button->set_icon_text_spacing(views::kItemLabelSpacing);
721 button->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList( 764 button->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
722 ui::ResourceBundle::MediumFont)); 765 ui::ResourceBundle::MediumFont));
723 button->set_border(NULL); 766 button->set_border(NULL);
724 767
725 layout->StartRow(1, 0); 768 layout->StartRow(1, 0);
726 layout->AddView(button); 769 layout->AddView(button);
727 770
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 // The primary account should always be listed first. 842 // The primary account should always be listed first.
800 // TODO(rogerta): we still need to further differentiate the primary account 843 // TODO(rogerta): we still need to further differentiate the primary account
801 // from the others in the UI, so more work is likely required here: 844 // from the others in the UI, so more work is likely required here:
802 // crbug.com/311124. 845 // crbug.com/311124.
803 CreateAccountButton(layout, primary_account, true); 846 CreateAccountButton(layout, primary_account, true);
804 for (size_t i = 0; i < accounts.size(); ++i) 847 for (size_t i = 0; i < accounts.size(); ++i)
805 CreateAccountButton(layout, accounts[i], false); 848 CreateAccountButton(layout, accounts[i], false);
806 849
807 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 850 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
808 851
809 add_account_button_ = new views::BlueButton( 852 // Elide the button text so that the contents fit inside the bubble.
810 this, 853 base::string16 elided_button_text =
811 l10n_util::GetStringFUTF16(IDS_PROFILES_PROFILE_ADD_ACCOUNT_BUTTON, 854 ElideText(l10n_util::GetStringFUTF16(
812 avatar_item.name)); 855 IDS_PROFILES_PROFILE_ADD_ACCOUNT_BUTTON, avatar_item.name),
856 kFixedMenuWidth - 2 * views::kButtonHEdgeMarginNew, // Width - insets.
857 ui::ResourceBundle::MediumFont);
858
859 add_account_button_ = new views::BlueButton(this, elided_button_text);
813 layout->StartRow(1, 0); 860 layout->StartRow(1, 0);
814 layout->AddView(add_account_button_); 861 layout->AddView(add_account_button_);
815 return view; 862 return view;
816 } 863 }
817 864
818 void ProfileChooserView::CreateAccountButton(views::GridLayout* layout, 865 void ProfileChooserView::CreateAccountButton(views::GridLayout* layout,
819 const std::string& account, 866 const std::string& account,
820 bool is_primary_account) { 867 bool is_primary_account) {
821 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 868 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
822 // Use a MenuButtonListener and not a regular ButtonListener to be 869 // Use a MenuButtonListener and not a regular ButtonListener to be
(...skipping 11 matching lines...) Expand all
834 email_button->set_menu_marker( 881 email_button->set_menu_marker(
835 rb->GetImageNamed(IDR_CLOSE_1).ToImageSkia()); 882 rb->GetImageNamed(IDR_CLOSE_1).ToImageSkia());
836 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 883 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
837 } 884 }
838 layout->StartRow(1, 0); 885 layout->StartRow(1, 0);
839 layout->AddView(email_button); 886 layout->AddView(email_button);
840 887
841 // Save the original email address, as the button text could be elided. 888 // Save the original email address, as the button text could be elided.
842 current_profile_accounts_map_[email_button] = account; 889 current_profile_accounts_map_[email_button] = account;
843 } 890 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698