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

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

Issue 2289143004: Add ink drop ripple (but no highlight) to comboboxes in harmony. (Closed)
Patch Set: . Created 4 years, 3 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
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
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "build/build_config.h" 13 #include "build/build_config.h"
14 #include "ui/accessibility/ax_view_state.h" 14 #include "ui/accessibility/ax_view_state.h"
15 #include "ui/base/default_style.h" 15 #include "ui/base/default_style.h"
16 #include "ui/base/ime/input_method.h" 16 #include "ui/base/ime/input_method.h"
17 #include "ui/base/material_design/material_design_controller.h"
17 #include "ui/base/models/combobox_model.h" 18 #include "ui/base/models/combobox_model.h"
18 #include "ui/base/models/combobox_model_observer.h" 19 #include "ui/base/models/combobox_model_observer.h"
19 #include "ui/base/resource/resource_bundle.h" 20 #include "ui/base/resource/resource_bundle.h"
20 #include "ui/events/event.h" 21 #include "ui/events/event.h"
21 #include "ui/gfx/animation/throb_animation.h" 22 #include "ui/gfx/animation/throb_animation.h"
22 #include "ui/gfx/canvas.h" 23 #include "ui/gfx/canvas.h"
23 #include "ui/gfx/color_palette.h" 24 #include "ui/gfx/color_palette.h"
24 #include "ui/gfx/scoped_canvas.h" 25 #include "ui/gfx/scoped_canvas.h"
25 #include "ui/gfx/text_utils.h" 26 #include "ui/gfx/text_utils.h"
26 #include "ui/native_theme/common_theme.h" 27 #include "ui/native_theme/common_theme.h"
27 #include "ui/native_theme/native_theme.h" 28 #include "ui/native_theme/native_theme.h"
28 #include "ui/native_theme/native_theme_aura.h" 29 #include "ui/native_theme/native_theme_aura.h"
29 #include "ui/resources/grit/ui_resources.h" 30 #include "ui/resources/grit/ui_resources.h"
31 #include "ui/views/animation/flood_fill_ink_drop_ripple.h"
32 #include "ui/views/animation/ink_drop_highlight.h"
30 #include "ui/views/background.h" 33 #include "ui/views/background.h"
31 #include "ui/views/controls/button/custom_button.h" 34 #include "ui/views/controls/button/custom_button.h"
32 #include "ui/views/controls/button/label_button.h" 35 #include "ui/views/controls/button/label_button.h"
33 #include "ui/views/controls/combobox/combobox_listener.h" 36 #include "ui/views/controls/combobox/combobox_listener.h"
34 #include "ui/views/controls/focusable_border.h" 37 #include "ui/views/controls/focusable_border.h"
35 #include "ui/views/controls/menu/menu_config.h" 38 #include "ui/views/controls/menu/menu_config.h"
36 #include "ui/views/controls/menu/menu_model_adapter.h" 39 #include "ui/views/controls/menu/menu_model_adapter.h"
37 #include "ui/views/controls/menu/menu_runner.h" 40 #include "ui/views/controls/menu/menu_runner.h"
38 #include "ui/views/controls/prefix_selector.h" 41 #include "ui/views/controls/prefix_selector.h"
39 #include "ui/views/controls/textfield/textfield.h" 42 #include "ui/views/controls/textfield/textfield.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 const int kHoveredMenuButtonImages[] = MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON_H); 84 const int kHoveredMenuButtonImages[] = MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON_H);
82 const int kPressedMenuButtonImages[] = MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON_P); 85 const int kPressedMenuButtonImages[] = MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON_P);
83 const int kFocusedMenuButtonImages[] = MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON_F); 86 const int kFocusedMenuButtonImages[] = MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON_F);
84 const int kFocusedHoveredMenuButtonImages[] = 87 const int kFocusedHoveredMenuButtonImages[] =
85 MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON_F_H); 88 MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON_F_H);
86 const int kFocusedPressedMenuButtonImages[] = 89 const int kFocusedPressedMenuButtonImages[] =
87 MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON_F_P); 90 MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON_F_P);
88 91
89 #undef MENU_IMAGE_GRID 92 #undef MENU_IMAGE_GRID
90 93
94 bool UseMd() {
95 return ui::MaterialDesignController::IsSecondaryUiMaterial();
96 }
97
91 gfx::Rect PositionArrowWithinContainer(const gfx::Rect& container_bounds, 98 gfx::Rect PositionArrowWithinContainer(const gfx::Rect& container_bounds,
92 const gfx::Size& arrow_size, 99 const gfx::Size& arrow_size,
93 Combobox::Style style) { 100 Combobox::Style style) {
94 gfx::Rect bounds(container_bounds); 101 gfx::Rect bounds(container_bounds);
95 if (style == Combobox::STYLE_ACTION) { 102 if (style == Combobox::STYLE_ACTION) {
96 // This positions the arrow horizontally. The later call to 103 // This positions the arrow horizontally. The later call to
97 // ClampToCenteredSize will position it vertically without touching the 104 // ClampToCenteredSize will position it vertically without touching the
98 // horizontal position. 105 // horizontal position.
99 bounds.Inset(kActionLeftPadding, 0, kActionRightPadding, 0); 106 bounds.Inset(kActionLeftPadding, 0, kActionRightPadding, 0);
100 DCHECK_EQ(bounds.width(), arrow_size.width()); 107 DCHECK_EQ(bounds.width(), arrow_size.width());
101 } 108 }
102 109
103 bounds.ClampToCenteredSize(arrow_size); 110 bounds.ClampToCenteredSize(arrow_size);
104 return bounds; 111 return bounds;
105 } 112 }
106 113
107 // The transparent button which holds a button state but is not rendered. 114 // The transparent button which holds a button state but is not rendered.
108 class TransparentButton : public CustomButton { 115 class TransparentButton : public CustomButton {
109 public: 116 public:
110 TransparentButton(ButtonListener* listener) 117 TransparentButton(ButtonListener* listener)
111 : CustomButton(listener) { 118 : CustomButton(listener) {
112 SetAnimationDuration(LabelButton::kHoverAnimationDurationMs); 119 SetAnimationDuration(LabelButton::kHoverAnimationDurationMs);
113 SetFocusBehavior(FocusBehavior::NEVER); 120 SetFocusBehavior(FocusBehavior::NEVER);
114 set_notify_action(PlatformStyle::kMenuNotifyActivationAction); 121 set_notify_action(PlatformStyle::kMenuNotifyActivationAction);
122
123 if (UseMd()) {
124 SetInkDropMode(PlatformStyle::kUseRipples ? InkDropMode::ON
125 : InkDropMode::OFF);
126 set_has_ink_drop_action_on_click(true);
127 }
115 } 128 }
116 ~TransparentButton() override {} 129 ~TransparentButton() override {}
117 130
118 #if !defined(OS_MACOSX)
119 // Override OnMousePressed() to transfer focus to the parent() on a click
120 // except on Mac, which doesn't transfer focus when buttons are clicked.
121 bool OnMousePressed(const ui::MouseEvent& mouse_event) override { 131 bool OnMousePressed(const ui::MouseEvent& mouse_event) override {
122 parent()->RequestFocus(); 132 if (!UseMd())
123 return true; 133 parent()->RequestFocus();
sky 2016/08/31 16:19:49 If you don't call RequestFocus then how is Combobo
Evan Stade 2016/08/31 21:12:29 You'd still get keyboard focus if you tabbed to th
sky 2016/08/31 21:53:04 I thought clicking on Transparentbutton only gave
Evan Stade 2016/08/31 21:59:38 Clicking on the transparent button gives focus to
134 return CustomButton::OnMousePressed(mouse_event);
124 } 135 }
125 #endif
126 136
127 double GetAnimationValue() const { 137 double GetAnimationValue() const {
128 return hover_animation().GetCurrentValue(); 138 return hover_animation().GetCurrentValue();
129 } 139 }
130 140
141 // Overridden from InkDropHost:
142 std::unique_ptr<InkDropRipple> CreateInkDropRipple() const override {
143 return std::unique_ptr<views::InkDropRipple>(
144 new views::FloodFillInkDropRipple(
145 GetLocalBounds(), GetInkDropCenterBasedOnLastEvent(),
146 GetNativeTheme()->GetSystemColor(
147 ui::NativeTheme::kColorId_LabelEnabledColor),
148 ink_drop_visible_opacity()));
149 }
150
151 std::unique_ptr<InkDropHighlight> CreateInkDropHighlight() const override {
152 return nullptr;
153 }
154
131 private: 155 private:
132 DISALLOW_COPY_AND_ASSIGN(TransparentButton); 156 DISALLOW_COPY_AND_ASSIGN(TransparentButton);
133 }; 157 };
134 158
135 // Returns the next or previous valid index (depending on |increment|'s value). 159 // Returns the next or previous valid index (depending on |increment|'s value).
136 // Skips separator or disabled indices. Returns -1 if there is no valid adjacent 160 // Skips separator or disabled indices. Returns -1 if there is no valid adjacent
137 // index. 161 // index.
138 int GetAdjacentIndex(ui::ComboboxModel* model, int increment, int index) { 162 int GetAdjacentIndex(ui::ComboboxModel* model, int increment, int index) {
139 DCHECK(increment == -1 || increment == 1); 163 DCHECK(increment == -1 || increment == 1);
140 164
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 if (invalid == invalid_) 498 if (invalid == invalid_)
475 return; 499 return;
476 500
477 invalid_ = invalid; 501 invalid_ = invalid;
478 502
479 UpdateBorder(); 503 UpdateBorder();
480 SchedulePaint(); 504 SchedulePaint();
481 } 505 }
482 506
483 void Combobox::Layout() { 507 void Combobox::Layout() {
484 PrefixDelegate::Layout(); 508 View::Layout();
485 509
486 int text_button_width = 0; 510 int text_button_width = 0;
487 int arrow_button_width = 0; 511 int arrow_button_width = 0;
488 512
489 switch (style_) { 513 switch (style_) {
490 case STYLE_NORMAL: { 514 case STYLE_NORMAL: {
491 arrow_button_width = width(); 515 arrow_button_width = width();
492 break; 516 break;
493 } 517 }
494 case STYLE_ACTION: { 518 case STYLE_ACTION: {
495 arrow_button_width = GetArrowContainerWidth(); 519 arrow_button_width = GetArrowContainerWidth();
496 text_button_width = width() - arrow_button_width; 520 text_button_width = width() - arrow_button_width;
497 break; 521 break;
498 } 522 }
499 } 523 }
500 524
501 int arrow_button_x = std::max(0, text_button_width); 525 int arrow_button_x = std::max(0, text_button_width);
502 text_button_->SetBounds(0, 0, std::max(0, text_button_width), height()); 526 text_button_->SetBounds(0, 0, std::max(0, text_button_width), height());
503 arrow_button_->SetBounds(arrow_button_x, 0, arrow_button_width, height()); 527 arrow_button_->SetBounds(arrow_button_x, 0, arrow_button_width, height());
504 } 528 }
505 529
506 void Combobox::OnEnabledChanged() { 530 void Combobox::OnEnabledChanged() {
507 PrefixDelegate::OnEnabledChanged(); 531 View::OnEnabledChanged();
508 arrow_image_ = PlatformStyle::CreateComboboxArrow(enabled(), style_); 532 arrow_image_ = PlatformStyle::CreateComboboxArrow(enabled(), style_);
509 } 533 }
510 534
511 int Combobox::GetRowCount() { 535 int Combobox::GetRowCount() {
512 return model()->GetItemCount(); 536 return model()->GetItemCount();
513 } 537 }
514 538
515 int Combobox::GetSelectedRow() { 539 int Combobox::GetSelectedRow() {
516 return selected_index_; 540 return selected_index_;
517 } 541 }
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 state->name = accessible_name_; 709 state->name = accessible_name_;
686 state->value = model_->GetItemAt(selected_index_); 710 state->value = model_->GetItemAt(selected_index_);
687 state->index = selected_index_; 711 state->index = selected_index_;
688 state->count = model_->GetItemCount(); 712 state->count = model_->GetItemCount();
689 } 713 }
690 714
691 void Combobox::ButtonPressed(Button* sender, const ui::Event& event) { 715 void Combobox::ButtonPressed(Button* sender, const ui::Event& event) {
692 if (!enabled()) 716 if (!enabled())
693 return; 717 return;
694 718
695 RequestFocus(); 719 if (!UseMd())
720 RequestFocus();
sky 2016/08/31 16:19:49 Similar comment as to above.
696 721
697 if (sender == text_button_) { 722 if (sender == text_button_) {
698 OnPerformAction(); 723 OnPerformAction();
699 } else { 724 } else {
700 DCHECK_EQ(arrow_button_, sender); 725 DCHECK_EQ(arrow_button_, sender);
701 // TODO(hajimehoshi): Fix the problem that the arrow button blinks when 726 // TODO(hajimehoshi): Fix the problem that the arrow button blinks when
702 // cliking this while the dropdown menu is opened. 727 // cliking this while the dropdown menu is opened.
703 const base::TimeDelta delta = base::Time::Now() - closed_time_; 728 const base::TimeDelta delta = base::Time::Now() - closed_time_;
704 if (delta.InMilliseconds() <= kMinimumMsBetweenButtonClicks) 729 if (delta.InMilliseconds() <= kMinimumMsBetweenButtonClicks)
705 return; 730 return;
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 if (size_to_largest_label_ || i == selected_index_) { 924 if (size_to_largest_label_ || i == selected_index_) {
900 width = std::max( 925 width = std::max(
901 width, gfx::GetStringWidth(menu_model_->GetLabelAt(i), font_list)); 926 width, gfx::GetStringWidth(menu_model_->GetLabelAt(i), font_list));
902 } 927 }
903 } 928 }
904 return gfx::Size(width, font_list.GetHeight()); 929 return gfx::Size(width, font_list.GetHeight());
905 } 930 }
906 931
907 PrefixSelector* Combobox::GetPrefixSelector() { 932 PrefixSelector* Combobox::GetPrefixSelector() {
908 if (!selector_) 933 if (!selector_)
909 selector_.reset(new PrefixSelector(this)); 934 selector_.reset(new PrefixSelector(this, this));
910 return selector_.get(); 935 return selector_.get();
911 } 936 }
912 937
913 int Combobox::GetArrowContainerWidth() const { 938 int Combobox::GetArrowContainerWidth() const {
914 int padding = style_ == STYLE_NORMAL 939 int padding = style_ == STYLE_NORMAL
915 ? PlatformStyle::kComboboxNormalArrowPadding * 2 940 ? PlatformStyle::kComboboxNormalArrowPadding * 2
916 : kActionLeftPadding + kActionRightPadding; 941 : kActionLeftPadding + kActionRightPadding;
917 return ArrowSize().width() + padding; 942 return ArrowSize().width() + padding;
918 } 943 }
919 944
920 } // namespace views 945 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698