| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/button/md_text_button.h" | 5 #include "ui/views/controls/button/md_text_button.h" |
| 6 | 6 |
| 7 #include "base/i18n/case_conversion.h" | 7 #include "base/i18n/case_conversion.h" |
| 8 #include "ui/base/material_design/material_design_controller.h" | 8 #include "ui/base/material_design/material_design_controller.h" |
| 9 #include "ui/gfx/canvas.h" |
| 9 #include "ui/gfx/color_utils.h" | 10 #include "ui/gfx/color_utils.h" |
| 10 #include "ui/native_theme/native_theme.h" | 11 #include "ui/native_theme/native_theme.h" |
| 11 #include "ui/views/background.h" | 12 #include "ui/views/background.h" |
| 12 #include "ui/views/border.h" | 13 #include "ui/views/border.h" |
| 13 #include "ui/views/controls/button/blue_button.h" | 14 #include "ui/views/controls/button/blue_button.h" |
| 14 #include "ui/views/painter.h" | 15 #include "ui/views/painter.h" |
| 15 | 16 |
| 16 namespace views { | 17 namespace views { |
| 17 | 18 |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| 21 // The amount to enlarge the focus border in all directions relative to the |
| 22 // button. |
| 23 const int kFocusBorderOutset = -2; |
| 24 |
| 25 // The corner radius of the focus border roundrect. |
| 26 const int kFocusBorderCornerRadius = 3; |
| 27 |
| 28 class MdFocusRing : public views::View { |
| 29 public: |
| 30 MdFocusRing() { |
| 31 SetPaintToLayer(true); |
| 32 layer()->SetFillsBoundsOpaquely(false); |
| 33 } |
| 34 ~MdFocusRing() override {} |
| 35 |
| 36 bool CanProcessEventsWithinSubtree() const override { return false; } |
| 37 |
| 38 void OnPaint(gfx::Canvas* canvas) override { |
| 39 MdTextButton::PaintMdFocusRing(canvas, this); |
| 40 } |
| 41 |
| 42 private: |
| 43 DISALLOW_COPY_AND_ASSIGN(MdFocusRing); |
| 44 }; |
| 45 |
| 20 // Inset between clickable region border and button contents (text). | 46 // Inset between clickable region border and button contents (text). |
| 21 const int kHorizontalPadding = 12; | 47 const int kHorizontalPadding = 12; |
| 22 const int kVerticalPadding = 6; | 48 const int kVerticalPadding = 6; |
| 23 | 49 |
| 24 // Minimum size to reserve for the button contents. | 50 // Minimum size to reserve for the button contents. |
| 25 const int kMinWidth = 48; | 51 const int kMinWidth = 48; |
| 26 | 52 |
| 27 LabelButton* CreateButton(ButtonListener* listener, | 53 LabelButton* CreateButton(ButtonListener* listener, |
| 28 const base::string16& text, | 54 const base::string16& text, |
| 29 bool md) { | 55 bool md) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 button->SetText(text); | 97 button->SetText(text); |
| 72 // TODO(estade): can we get rid of the platform style border hoopla if | 98 // TODO(estade): can we get rid of the platform style border hoopla if |
| 73 // we apply the MD treatment to all buttons, even GTK buttons? | 99 // we apply the MD treatment to all buttons, even GTK buttons? |
| 74 button->SetBorder( | 100 button->SetBorder( |
| 75 Border::CreateEmptyBorder(kVerticalPadding, kHorizontalPadding, | 101 Border::CreateEmptyBorder(kVerticalPadding, kHorizontalPadding, |
| 76 kVerticalPadding, kHorizontalPadding)); | 102 kVerticalPadding, kHorizontalPadding)); |
| 77 button->SetFocusForPlatform(); | 103 button->SetFocusForPlatform(); |
| 78 return button; | 104 return button; |
| 79 } | 105 } |
| 80 | 106 |
| 107 // static |
| 108 void MdTextButton::PaintMdFocusRing(gfx::Canvas* canvas, views::View* view) { |
| 109 SkPaint paint; |
| 110 paint.setAntiAlias(true); |
| 111 paint.setColor(view->GetNativeTheme()->GetSystemColor( |
| 112 ui::NativeTheme::kColorId_CallToActionColor)); |
| 113 paint.setStyle(SkPaint::kStroke_Style); |
| 114 paint.setStrokeWidth(1); |
| 115 gfx::RectF rect(view->GetLocalBounds()); |
| 116 rect.Inset(gfx::InsetsF(0.5)); |
| 117 canvas->DrawRoundRect(rect, kFocusBorderCornerRadius, paint); |
| 118 } |
| 119 |
| 81 void MdTextButton::SetCallToAction(CallToAction cta) { | 120 void MdTextButton::SetCallToAction(CallToAction cta) { |
| 82 if (cta_ == cta) | 121 if (cta_ == cta) |
| 83 return; | 122 return; |
| 84 | 123 |
| 85 cta_ = cta; | 124 cta_ = cta; |
| 86 UpdateColorsFromNativeTheme(); | 125 UpdateColorsFromNativeTheme(); |
| 87 } | 126 } |
| 88 | 127 |
| 128 void MdTextButton::Layout() { |
| 129 gfx::Rect focus_bounds = GetLocalBounds(); |
| 130 focus_bounds.Inset(gfx::Insets(kFocusBorderOutset)); |
| 131 focus_ring_->SetBoundsRect(focus_bounds); |
| 132 } |
| 133 |
| 134 void MdTextButton::OnFocus() { |
| 135 LabelButton::OnFocus(); |
| 136 focus_ring_->SetVisible(true); |
| 137 } |
| 138 |
| 139 void MdTextButton::OnBlur() { |
| 140 LabelButton::OnBlur(); |
| 141 focus_ring_->SetVisible(false); |
| 142 } |
| 143 |
| 89 void MdTextButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 144 void MdTextButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
| 90 LabelButton::OnNativeThemeChanged(theme); | 145 LabelButton::OnNativeThemeChanged(theme); |
| 91 UpdateColorsFromNativeTheme(); | 146 UpdateColorsFromNativeTheme(); |
| 92 } | 147 } |
| 93 | 148 |
| 94 SkColor MdTextButton::GetInkDropBaseColor() const { | 149 SkColor MdTextButton::GetInkDropBaseColor() const { |
| 95 return color_utils::DeriveDefaultIconColor(label()->enabled_color()); | 150 return color_utils::DeriveDefaultIconColor(label()->enabled_color()); |
| 96 } | 151 } |
| 97 | 152 |
| 153 bool MdTextButton::ShouldShowInkDropForFocus() const { |
| 154 // These types of button use |focus_ring_|. |
| 155 return false; |
| 156 } |
| 157 |
| 98 void MdTextButton::SetText(const base::string16& text) { | 158 void MdTextButton::SetText(const base::string16& text) { |
| 99 LabelButton::SetText(base::i18n::ToUpper(text)); | 159 LabelButton::SetText(base::i18n::ToUpper(text)); |
| 100 } | 160 } |
| 101 | 161 |
| 102 void MdTextButton::UpdateStyleToIndicateDefaultStatus() { | 162 void MdTextButton::UpdateStyleToIndicateDefaultStatus() { |
| 103 // Update the call to action state to reflect defaultness. Don't change strong | 163 // Update the call to action state to reflect defaultness. Don't change strong |
| 104 // call to action to weak. | 164 // call to action to weak. |
| 105 if (!is_default()) | 165 if (!is_default()) |
| 106 SetCallToAction(NO_CALL_TO_ACTION); | 166 SetCallToAction(NO_CALL_TO_ACTION); |
| 107 else if (cta_ == NO_CALL_TO_ACTION) | 167 else if (cta_ == NO_CALL_TO_ACTION) |
| 108 SetCallToAction(WEAK_CALL_TO_ACTION); | 168 SetCallToAction(WEAK_CALL_TO_ACTION); |
| 109 } | 169 } |
| 110 | 170 |
| 111 MdTextButton::MdTextButton(ButtonListener* listener) | 171 MdTextButton::MdTextButton(ButtonListener* listener) |
| 112 : LabelButton(listener, base::string16()), | 172 : LabelButton(listener, base::string16()), |
| 113 ink_drop_delegate_(this, this), | 173 focus_ring_(new MdFocusRing()), |
| 114 cta_(NO_CALL_TO_ACTION) { | 174 cta_(NO_CALL_TO_ACTION) { |
| 115 set_ink_drop_delegate(&ink_drop_delegate_); | 175 set_ink_drop_delegate( |
| 176 base::WrapUnique(new ButtonInkDropDelegate(this, this))); |
| 116 set_has_ink_drop_action_on_click(true); | 177 set_has_ink_drop_action_on_click(true); |
| 117 SetHorizontalAlignment(gfx::ALIGN_CENTER); | 178 SetHorizontalAlignment(gfx::ALIGN_CENTER); |
| 118 SetFocusForPlatform(); | 179 SetFocusForPlatform(); |
| 119 SetMinSize(gfx::Size(kMinWidth, 0)); | 180 SetMinSize(gfx::Size(kMinWidth, 0)); |
| 120 SetFocusPainter(nullptr); | 181 SetFocusPainter(nullptr); |
| 121 UseMdFocusRing(); | |
| 122 label()->SetAutoColorReadabilityEnabled(false); | 182 label()->SetAutoColorReadabilityEnabled(false); |
| 183 |
| 184 AddChildView(focus_ring_); |
| 185 focus_ring_->SetVisible(false); |
| 186 set_request_focus_on_press(false); |
| 123 } | 187 } |
| 124 | 188 |
| 125 MdTextButton::~MdTextButton() {} | 189 MdTextButton::~MdTextButton() {} |
| 126 | 190 |
| 127 void MdTextButton::UpdateColorsFromNativeTheme() { | 191 void MdTextButton::UpdateColorsFromNativeTheme() { |
| 128 ui::NativeTheme::ColorId fg_color_id = ui::NativeTheme::kColorId_NumColors; | 192 ui::NativeTheme::ColorId fg_color_id = ui::NativeTheme::kColorId_NumColors; |
| 129 switch (cta_) { | 193 switch (cta_) { |
| 130 case NO_CALL_TO_ACTION: | 194 case NO_CALL_TO_ACTION: |
| 131 // When there's no call to action, respect a color override if one has | 195 // When there's no call to action, respect a color override if one has |
| 132 // been set. For other call to action states, don't let individual buttons | 196 // been set. For other call to action states, don't let individual buttons |
| (...skipping 16 matching lines...) Expand all Loading... |
| 149 cta_ == STRONG_CALL_TO_ACTION | 213 cta_ == STRONG_CALL_TO_ACTION |
| 150 ? Background::CreateBackgroundPainter( | 214 ? Background::CreateBackgroundPainter( |
| 151 true, Painter::CreateSolidRoundRectPainter( | 215 true, Painter::CreateSolidRoundRectPainter( |
| 152 theme->GetSystemColor( | 216 theme->GetSystemColor( |
| 153 ui::NativeTheme::kColorId_CallToActionColor), | 217 ui::NativeTheme::kColorId_CallToActionColor), |
| 154 kInkDropSmallCornerRadius)) | 218 kInkDropSmallCornerRadius)) |
| 155 : nullptr); | 219 : nullptr); |
| 156 } | 220 } |
| 157 | 221 |
| 158 } // namespace views | 222 } // namespace views |
| OLD | NEW |