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

Side by Side Diff: ui/views/controls/combobox/combobox.cc

Issue 1971333002: Views: factor out Combobox background and const-ify style (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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
« no previous file with comments | « ui/views/controls/combobox/combobox.h ('k') | ui/views/controls/combobox/combobox_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "ui/views/controls/combobox/combobox.h" 5 #include "ui/views/controls/combobox/combobox.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 namespace { 47 namespace {
48 48
49 // Menu border widths 49 // Menu border widths
50 const int kMenuBorderWidthLeft = 1; 50 const int kMenuBorderWidthLeft = 1;
51 const int kMenuBorderWidthTop = 1; 51 const int kMenuBorderWidthTop = 1;
52 const int kMenuBorderWidthRight = 1; 52 const int kMenuBorderWidthRight = 1;
53 53
54 // Limit how small a combobox can be. 54 // Limit how small a combobox can be.
55 const int kMinComboboxWidth = 25; 55 const int kMinComboboxWidth = 25;
56 56
57 // Size of the combobox arrow margins
58 const int kDisclosureArrowLeftPadding = 7;
59 const int kDisclosureArrowRightPadding = 7;
60 const int kDisclosureArrowButtonLeftPadding = 11;
61 const int kDisclosureArrowButtonRightPadding = 12;
tapted 2016/05/13 07:51:02 So there's still the same concern that the alignme
Elly Fong-Jones 2016/05/16 21:45:44 Done.
62
63 // Define the id of the first item in the menu (since it needs to be > 0) 57 // Define the id of the first item in the menu (since it needs to be > 0)
64 const int kFirstMenuItemId = 1000; 58 const int kFirstMenuItemId = 1000;
65 59
66 // Used to indicate that no item is currently selected by the user. 60 // Used to indicate that no item is currently selected by the user.
67 const int kNoSelection = -1; 61 const int kNoSelection = -1;
68 62
69 const int kBodyButtonImages[] = IMAGE_GRID(IDR_COMBOBOX_BUTTON); 63 const int kBodyButtonImages[] = IMAGE_GRID(IDR_COMBOBOX_BUTTON);
70 const int kHoveredBodyButtonImages[] = IMAGE_GRID(IDR_COMBOBOX_BUTTON_H); 64 const int kHoveredBodyButtonImages[] = IMAGE_GRID(IDR_COMBOBOX_BUTTON_H);
71 const int kPressedBodyButtonImages[] = IMAGE_GRID(IDR_COMBOBOX_BUTTON_P); 65 const int kPressedBodyButtonImages[] = IMAGE_GRID(IDR_COMBOBOX_BUTTON_P);
72 const int kFocusedBodyButtonImages[] = IMAGE_GRID(IDR_COMBOBOX_BUTTON_F); 66 const int kFocusedBodyButtonImages[] = IMAGE_GRID(IDR_COMBOBOX_BUTTON_F);
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 330
337 Combobox* owner_; // Weak. Owns this. 331 Combobox* owner_; // Weak. Owns this.
338 ui::ComboboxModel* model_; // Weak. 332 ui::ComboboxModel* model_; // Weak.
339 333
340 DISALLOW_COPY_AND_ASSIGN(ComboboxMenuModelAdapter); 334 DISALLOW_COPY_AND_ASSIGN(ComboboxMenuModelAdapter);
341 }; 335 };
342 336
343 //////////////////////////////////////////////////////////////////////////////// 337 ////////////////////////////////////////////////////////////////////////////////
344 // Combobox, public: 338 // Combobox, public:
345 339
346 Combobox::Combobox(ui::ComboboxModel* model) 340 Combobox::Combobox(ui::ComboboxModel* model, Style style)
347 : model_(model), 341 : model_(model),
348 style_(STYLE_NORMAL), 342 style_(style),
349 listener_(NULL), 343 listener_(NULL),
350 selected_index_(model_->GetDefaultIndex()), 344 selected_index_(model_->GetDefaultIndex()),
351 invalid_(false), 345 invalid_(false),
352 menu_model_adapter_(new ComboboxMenuModelAdapter(this, model)), 346 menu_model_adapter_(new ComboboxMenuModelAdapter(this, model)),
353 text_button_(new TransparentButton(this)), 347 text_button_(new TransparentButton(this)),
354 arrow_button_(new TransparentButton(this)), 348 arrow_button_(new TransparentButton(this)),
355 weak_ptr_factory_(this) { 349 weak_ptr_factory_(this) {
350 if (style_ == STYLE_ACTION)
351 selected_index_ = 0;
352
356 ModelChanged(); 353 ModelChanged();
357 #if defined(OS_MACOSX) 354 #if defined(OS_MACOSX)
358 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); 355 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
359 #else 356 #else
360 SetFocusBehavior(FocusBehavior::ALWAYS); 357 SetFocusBehavior(FocusBehavior::ALWAYS);
361 #endif 358 #endif
362 359
363 UpdateBorder(); 360 UpdateBorder();
361 arrow_image_ = PlatformStyle::CreateComboboxArrow(enabled(), style);
364 // set_background() takes ownership but takes a raw pointer. 362 // set_background() takes ownership but takes a raw pointer.
365 std::unique_ptr<Background> b = PlatformStyle::CreateComboboxBackground(); 363 std::unique_ptr<Background> b =
364 PlatformStyle::CreateComboboxBackground(GetShoulderWidth());
366 set_background(b.release()); 365 set_background(b.release());
367 366
368 // Initialize the button images. 367 // Initialize the button images.
369 Button::ButtonState button_states[] = { 368 Button::ButtonState button_states[] = {
370 Button::STATE_DISABLED, 369 Button::STATE_DISABLED,
371 Button::STATE_NORMAL, 370 Button::STATE_NORMAL,
372 Button::STATE_HOVERED, 371 Button::STATE_HOVERED,
373 Button::STATE_PRESSED, 372 Button::STATE_PRESSED,
374 }; 373 };
375 for (int i = 0; i < 2; i++) { 374 for (int i = 0; i < 2; i++) {
(...skipping 21 matching lines...) Expand all
397 DCHECK(selector_.get() != GetInputMethod()->GetTextInputClient()); 396 DCHECK(selector_.get() != GetInputMethod()->GetTextInputClient());
398 } 397 }
399 } 398 }
400 399
401 // static 400 // static
402 const gfx::FontList& Combobox::GetFontList() { 401 const gfx::FontList& Combobox::GetFontList() {
403 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 402 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
404 return rb.GetFontListWithDelta(ui::kLabelFontSizeDelta); 403 return rb.GetFontListWithDelta(ui::kLabelFontSizeDelta);
405 } 404 }
406 405
407 void Combobox::SetStyle(Style style) {
408 if (style_ == style)
409 return;
410
411 style_ = style;
412 if (style_ == STYLE_ACTION)
413 selected_index_ = 0;
414
415 UpdateBorder();
416 content_size_ = GetContentSize();
417 PreferredSizeChanged();
418 }
419
420 void Combobox::ModelChanged() { 406 void Combobox::ModelChanged() {
421 // If the selection is no longer valid (or the model is empty), restore the 407 // If the selection is no longer valid (or the model is empty), restore the
422 // default index. 408 // default index.
423 if (selected_index_ >= model_->GetItemCount() || 409 if (selected_index_ >= model_->GetItemCount() ||
424 model_->GetItemCount() == 0 || 410 model_->GetItemCount() == 0 ||
425 model_->IsItemSeparatorAt(selected_index_)) { 411 model_->IsItemSeparatorAt(selected_index_)) {
426 selected_index_ = model_->GetDefaultIndex(); 412 selected_index_ = model_->GetDefaultIndex();
427 } 413 }
428 414
429 content_size_ = GetContentSize(); 415 content_size_ = GetContentSize();
(...skipping 28 matching lines...) Expand all
458 void Combobox::SetInvalid(bool invalid) { 444 void Combobox::SetInvalid(bool invalid) {
459 if (invalid == invalid_) 445 if (invalid == invalid_)
460 return; 446 return;
461 447
462 invalid_ = invalid; 448 invalid_ = invalid;
463 449
464 UpdateBorder(); 450 UpdateBorder();
465 SchedulePaint(); 451 SchedulePaint();
466 } 452 }
467 453
468 int Combobox::GetArrowButtonWidth() const {
469 return GetDisclosureArrowLeftPadding() +
470 ArrowSize().width() +
471 GetDisclosureArrowRightPadding();
472 }
473
474 void Combobox::Layout() { 454 void Combobox::Layout() {
475 PrefixDelegate::Layout(); 455 PrefixDelegate::Layout();
476 456
477 gfx::Insets insets = GetInsets(); 457 gfx::Insets insets = GetInsets();
478 int text_button_width = 0; 458 int text_button_width = 0;
479 int arrow_button_width = 0; 459 int arrow_button_width = 0;
480 460
481 switch (style_) { 461 switch (style_) {
482 case STYLE_NORMAL: { 462 case STYLE_NORMAL: {
483 arrow_button_width = width(); 463 arrow_button_width = width();
484 break; 464 break;
485 } 465 }
486 case STYLE_ACTION: { 466 case STYLE_ACTION: {
487 arrow_button_width = GetDisclosureArrowLeftPadding() + 467 arrow_button_width = GetShoulderWidth();
488 ArrowSize().width() +
489 GetDisclosureArrowRightPadding();
490 text_button_width = width() - arrow_button_width; 468 text_button_width = width() - arrow_button_width;
491 break; 469 break;
492 } 470 }
493 } 471 }
494 472
495 int arrow_button_x = std::max(0, text_button_width); 473 int arrow_button_x = std::max(0, text_button_width);
496 text_button_->SetBounds(0, 0, std::max(0, text_button_width), height()); 474 text_button_->SetBounds(0, 0, std::max(0, text_button_width), height());
497 arrow_button_->SetBounds(arrow_button_x, 0, arrow_button_width, height()); 475 arrow_button_->SetBounds(arrow_button_x, 0, arrow_button_width, height());
498 } 476 }
499 477
478 void Combobox::OnEnabledChanged() {
479 PrefixDelegate::OnEnabledChanged();
480 arrow_image_ = PlatformStyle::CreateComboboxArrow(enabled(), style_);
481 }
482
500 int Combobox::GetRowCount() { 483 int Combobox::GetRowCount() {
501 return model()->GetItemCount(); 484 return model()->GetItemCount();
502 } 485 }
503 486
504 int Combobox::GetSelectedRow() { 487 int Combobox::GetSelectedRow() {
505 return selected_index_; 488 return selected_index_;
506 } 489 }
507 490
508 void Combobox::SetSelectedRow(int row) { 491 void Combobox::SetSelectedRow(int row) {
509 int prev_index = selected_index_; 492 int prev_index = selected_index_;
(...skipping 12 matching lines...) Expand all
522 505
523 gfx::Size Combobox::GetPreferredSize() const { 506 gfx::Size Combobox::GetPreferredSize() const {
524 // The preferred size will drive the local bounds which in turn is used to set 507 // The preferred size will drive the local bounds which in turn is used to set
525 // the minimum width for the dropdown list. 508 // the minimum width for the dropdown list.
526 gfx::Insets insets = GetInsets(); 509 gfx::Insets insets = GetInsets();
527 insets += gfx::Insets(Textfield::kTextPadding, 510 insets += gfx::Insets(Textfield::kTextPadding,
528 Textfield::kTextPadding, 511 Textfield::kTextPadding,
529 Textfield::kTextPadding, 512 Textfield::kTextPadding,
530 Textfield::kTextPadding); 513 Textfield::kTextPadding);
531 int total_width = std::max(kMinComboboxWidth, content_size_.width()) + 514 int total_width = std::max(kMinComboboxWidth, content_size_.width()) +
532 insets.width() + GetDisclosureArrowLeftPadding() + 515 insets.width() + GetShoulderWidth();
533 ArrowSize().width() + GetDisclosureArrowRightPadding();
534 return gfx::Size(total_width, content_size_.height() + insets.height()); 516 return gfx::Size(total_width, content_size_.height() + insets.height());
535 } 517 }
536 518
537 const char* Combobox::GetClassName() const { 519 const char* Combobox::GetClassName() const {
538 return kViewClassName; 520 return kViewClassName;
539 } 521 }
540 522
541 bool Combobox::SkipDefaultKeyEventProcessing(const ui::KeyEvent& e) { 523 bool Combobox::SkipDefaultKeyEventProcessing(const ui::KeyEvent& e) {
542 // Escape should close the drop down list when it is active, not host UI. 524 // Escape should close the drop down list when it is active, not host UI.
543 if (e.key_code() != ui::VKEY_ESCAPE || 525 if (e.key_code() != ui::VKEY_ESCAPE ||
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 enabled() ? ui::NativeTheme::kColorId_LabelEnabledColor : 713 enabled() ? ui::NativeTheme::kColorId_LabelEnabledColor :
732 ui::NativeTheme::kColorId_LabelDisabledColor); 714 ui::NativeTheme::kColorId_LabelDisabledColor);
733 715
734 DCHECK_GE(selected_index_, 0); 716 DCHECK_GE(selected_index_, 0);
735 DCHECK_LT(selected_index_, model()->GetItemCount()); 717 DCHECK_LT(selected_index_, model()->GetItemCount());
736 if (selected_index_ < 0 || selected_index_ > model()->GetItemCount()) 718 if (selected_index_ < 0 || selected_index_ > model()->GetItemCount())
737 selected_index_ = 0; 719 selected_index_ = 0;
738 base::string16 text = model()->GetItemAt(selected_index_); 720 base::string16 text = model()->GetItemAt(selected_index_);
739 721
740 gfx::Size arrow_size = ArrowSize(); 722 gfx::Size arrow_size = ArrowSize();
741 int disclosure_arrow_offset = width() - arrow_size.width() - 723 int disclosure_arrow_offset = width() - GetShoulderWidth();
742 GetDisclosureArrowLeftPadding() - GetDisclosureArrowRightPadding();
743 724
744 const gfx::FontList& font_list = Combobox::GetFontList(); 725 const gfx::FontList& font_list = Combobox::GetFontList();
745 int text_width = gfx::GetStringWidth(text, font_list); 726 int text_width = gfx::GetStringWidth(text, font_list);
746 if ((text_width + insets.width()) > disclosure_arrow_offset) 727 if ((text_width + insets.width()) > disclosure_arrow_offset)
747 text_width = disclosure_arrow_offset - insets.width(); 728 text_width = disclosure_arrow_offset - insets.width();
748 729
749 gfx::Rect text_bounds(x, y, text_width, text_height); 730 gfx::Rect text_bounds(x, y, text_width, text_height);
750 AdjustBoundsForRTLUI(&text_bounds); 731 AdjustBoundsForRTLUI(&text_bounds);
751 canvas->DrawStringRect(text, font_list, text_color, text_bounds); 732 canvas->DrawStringRect(text, font_list, text_color, text_bounds);
752 733
753 int arrow_x = disclosure_arrow_offset + GetDisclosureArrowLeftPadding(); 734 gfx::Rect arrow_bounds(disclosure_arrow_offset, 0, GetShoulderWidth(),
754 gfx::Rect arrow_bounds(arrow_x, 735 height());
755 height() / 2 - arrow_size.height() / 2, 736 arrow_bounds.ClampToCenteredSize(ArrowSize());
tapted 2016/05/13 07:51:01 e.g. after this might need a 1-pixel adjustment to
Elly Fong-Jones 2016/05/16 21:45:44 Done.
756 arrow_size.width(),
757 arrow_size.height());
758 AdjustBoundsForRTLUI(&arrow_bounds); 737 AdjustBoundsForRTLUI(&arrow_bounds);
759 738
760 gfx::ImageSkia arrow_image = PlatformStyle::CreateComboboxArrow( 739 canvas->DrawImageInt(arrow_image_, arrow_bounds.x(), arrow_bounds.y());
761 enabled(), style_);
762 canvas->DrawImageInt(arrow_image, arrow_bounds.x(), arrow_bounds.y());
763 } 740 }
764 741
765 void Combobox::PaintButtons(gfx::Canvas* canvas) { 742 void Combobox::PaintButtons(gfx::Canvas* canvas) {
766 DCHECK(style_ == STYLE_ACTION); 743 DCHECK(style_ == STYLE_ACTION);
767 744
768 gfx::ScopedCanvas scoped_canvas(canvas); 745 gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, bounds());
769 if (base::i18n::IsRTL()) {
770 canvas->Translate(gfx::Vector2d(width(), 0));
771 canvas->Scale(-1, 1);
772 }
773 746
774 bool focused = HasFocus(); 747 bool focused = HasFocus();
775 const std::vector<const gfx::ImageSkia*>& arrow_button_images = 748 const std::vector<const gfx::ImageSkia*>& arrow_button_images =
776 menu_button_images_[focused][ 749 menu_button_images_[focused][
777 arrow_button_->state() == Button::STATE_HOVERED ? 750 arrow_button_->state() == Button::STATE_HOVERED ?
778 Button::STATE_NORMAL : arrow_button_->state()]; 751 Button::STATE_NORMAL : arrow_button_->state()];
779 752
780 int text_button_hover_alpha = 753 int text_button_hover_alpha =
781 text_button_->state() == Button::STATE_PRESSED ? 0 : 754 text_button_->state() == Button::STATE_PRESSED ? 0 :
782 static_cast<int>(static_cast<TransparentButton*>(text_button_)-> 755 static_cast<int>(static_cast<TransparentButton*>(text_button_)->
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 843
871 // This combobox may be deleted by the listener. 844 // This combobox may be deleted by the listener.
872 base::WeakPtr<Combobox> weak_ptr = weak_ptr_factory_.GetWeakPtr(); 845 base::WeakPtr<Combobox> weak_ptr = weak_ptr_factory_.GetWeakPtr();
873 if (listener_) 846 if (listener_)
874 listener_->OnPerformAction(this); 847 listener_->OnPerformAction(this);
875 848
876 if (weak_ptr && style_ == STYLE_ACTION) 849 if (weak_ptr && style_ == STYLE_ACTION)
877 selected_index_ = 0; 850 selected_index_ = 0;
878 } 851 }
879 852
880 int Combobox::GetDisclosureArrowLeftPadding() const {
881 switch (style_) {
882 case STYLE_NORMAL:
883 return kDisclosureArrowLeftPadding;
884 case STYLE_ACTION:
885 return kDisclosureArrowButtonLeftPadding;
886 }
887 NOTREACHED();
888 return 0;
889 }
890
891 int Combobox::GetDisclosureArrowRightPadding() const {
892 switch (style_) {
893 case STYLE_NORMAL:
894 return kDisclosureArrowRightPadding;
895 case STYLE_ACTION:
896 return kDisclosureArrowButtonRightPadding;
897 }
898 NOTREACHED();
899 return 0;
900 }
901
902 gfx::Size Combobox::ArrowSize() const { 853 gfx::Size Combobox::ArrowSize() const {
903 return PlatformStyle::CreateComboboxArrow(enabled(), style_).size(); 854 return arrow_image_.size();
904 } 855 }
905 856
906 gfx::Size Combobox::GetContentSize() const { 857 gfx::Size Combobox::GetContentSize() const {
907 const gfx::FontList& font_list = GetFontList(); 858 const gfx::FontList& font_list = GetFontList();
908 859
909 int width = 0; 860 int width = 0;
910 for (int i = 0; i < model()->GetItemCount(); ++i) { 861 for (int i = 0; i < model()->GetItemCount(); ++i) {
911 if (model_->IsItemSeparatorAt(i)) 862 if (model_->IsItemSeparatorAt(i))
912 continue; 863 continue;
913 864
914 if (style_ != STYLE_ACTION || i == selected_index_) { 865 if (style_ != STYLE_ACTION || i == selected_index_) {
915 width = std::max( 866 width = std::max(
916 width, 867 width,
917 gfx::GetStringWidth(menu_model_adapter_->GetLabelAt(i), font_list)); 868 gfx::GetStringWidth(menu_model_adapter_->GetLabelAt(i), font_list));
918 } 869 }
919 } 870 }
920 return gfx::Size(width, font_list.GetHeight()); 871 return gfx::Size(width, font_list.GetHeight());
921 } 872 }
922 873
923 PrefixSelector* Combobox::GetPrefixSelector() { 874 PrefixSelector* Combobox::GetPrefixSelector() {
924 if (!selector_) 875 if (!selector_)
925 selector_.reset(new PrefixSelector(this)); 876 selector_.reset(new PrefixSelector(this));
926 return selector_.get(); 877 return selector_.get();
927 } 878 }
928 879
880 int Combobox::GetShoulderWidth() const {
881 const int kNormalPadding = 7;
882 const int kActionPadding = 11;
883 int padding = style_ == STYLE_NORMAL ? kNormalPadding : kActionPadding;
884 return ArrowSize().width() + 2 * padding;
tapted 2016/05/13 07:51:01 e.g. This will now be 22px for action-style combos
Elly Fong-Jones 2016/05/16 21:45:44 Done.
885 }
886
929 } // namespace views 887 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/combobox/combobox.h ('k') | ui/views/controls/combobox/combobox_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698