| 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 LabelButton::Layout(); |
| 130 gfx::Rect focus_bounds = GetLocalBounds(); |
| 131 focus_bounds.Inset(gfx::Insets(kFocusBorderOutset)); |
| 132 focus_ring_->SetBoundsRect(focus_bounds); |
| 133 } |
| 134 |
| 135 void MdTextButton::OnFocus() { |
| 136 LabelButton::OnFocus(); |
| 137 focus_ring_->SetVisible(true); |
| 138 } |
| 139 |
| 140 void MdTextButton::OnBlur() { |
| 141 LabelButton::OnBlur(); |
| 142 focus_ring_->SetVisible(false); |
| 143 } |
| 144 |
| 89 void MdTextButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 145 void MdTextButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
| 90 LabelButton::OnNativeThemeChanged(theme); | 146 LabelButton::OnNativeThemeChanged(theme); |
| 91 UpdateColorsFromNativeTheme(); | 147 UpdateColorsFromNativeTheme(); |
| 92 } | 148 } |
| 93 | 149 |
| 94 SkColor MdTextButton::GetInkDropBaseColor() const { | 150 SkColor MdTextButton::GetInkDropBaseColor() const { |
| 95 return color_utils::DeriveDefaultIconColor(label()->enabled_color()); | 151 return color_utils::DeriveDefaultIconColor(label()->enabled_color()); |
| 96 } | 152 } |
| 97 | 153 |
| 154 bool MdTextButton::ShouldShowInkDropForFocus() const { |
| 155 // These types of button use |focus_ring_|. |
| 156 return false; |
| 157 } |
| 158 |
| 98 void MdTextButton::SetText(const base::string16& text) { | 159 void MdTextButton::SetText(const base::string16& text) { |
| 99 LabelButton::SetText(base::i18n::ToUpper(text)); | 160 LabelButton::SetText(base::i18n::ToUpper(text)); |
| 100 } | 161 } |
| 101 | 162 |
| 102 void MdTextButton::UpdateStyleToIndicateDefaultStatus() { | 163 void MdTextButton::UpdateStyleToIndicateDefaultStatus() { |
| 103 // Update the call to action state to reflect defaultness. Don't change strong | 164 // Update the call to action state to reflect defaultness. Don't change strong |
| 104 // call to action to weak. | 165 // call to action to weak. |
| 105 if (!is_default()) | 166 if (!is_default()) |
| 106 SetCallToAction(NO_CALL_TO_ACTION); | 167 SetCallToAction(NO_CALL_TO_ACTION); |
| 107 else if (cta_ == NO_CALL_TO_ACTION) | 168 else if (cta_ == NO_CALL_TO_ACTION) |
| 108 SetCallToAction(WEAK_CALL_TO_ACTION); | 169 SetCallToAction(WEAK_CALL_TO_ACTION); |
| 109 } | 170 } |
| 110 | 171 |
| 111 MdTextButton::MdTextButton(ButtonListener* listener) | 172 MdTextButton::MdTextButton(ButtonListener* listener) |
| 112 : LabelButton(listener, base::string16()), | 173 : LabelButton(listener, base::string16()), |
| 113 ink_drop_delegate_(this, this), | 174 focus_ring_(new MdFocusRing()), |
| 114 cta_(NO_CALL_TO_ACTION) { | 175 cta_(NO_CALL_TO_ACTION) { |
| 115 set_ink_drop_delegate(&ink_drop_delegate_); | 176 set_ink_drop_delegate( |
| 177 base::WrapUnique(new ButtonInkDropDelegate(this, this))); |
| 116 set_has_ink_drop_action_on_click(true); | 178 set_has_ink_drop_action_on_click(true); |
| 117 SetHorizontalAlignment(gfx::ALIGN_CENTER); | 179 SetHorizontalAlignment(gfx::ALIGN_CENTER); |
| 118 SetFocusForPlatform(); | 180 SetFocusForPlatform(); |
| 119 SetMinSize(gfx::Size(kMinWidth, 0)); | 181 SetMinSize(gfx::Size(kMinWidth, 0)); |
| 120 SetFocusPainter(nullptr); | 182 SetFocusPainter(nullptr); |
| 121 UseMdFocusRing(); | |
| 122 label()->SetAutoColorReadabilityEnabled(false); | 183 label()->SetAutoColorReadabilityEnabled(false); |
| 184 |
| 185 AddChildView(focus_ring_); |
| 186 focus_ring_->SetVisible(false); |
| 187 set_request_focus_on_press(false); |
| 123 } | 188 } |
| 124 | 189 |
| 125 MdTextButton::~MdTextButton() {} | 190 MdTextButton::~MdTextButton() {} |
| 126 | 191 |
| 127 void MdTextButton::UpdateColorsFromNativeTheme() { | 192 void MdTextButton::UpdateColorsFromNativeTheme() { |
| 128 ui::NativeTheme::ColorId fg_color_id = ui::NativeTheme::kColorId_NumColors; | 193 ui::NativeTheme::ColorId fg_color_id = ui::NativeTheme::kColorId_NumColors; |
| 129 switch (cta_) { | 194 switch (cta_) { |
| 130 case NO_CALL_TO_ACTION: | 195 case NO_CALL_TO_ACTION: |
| 131 // When there's no call to action, respect a color override if one has | 196 // 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 | 197 // 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 | 214 cta_ == STRONG_CALL_TO_ACTION |
| 150 ? Background::CreateBackgroundPainter( | 215 ? Background::CreateBackgroundPainter( |
| 151 true, Painter::CreateSolidRoundRectPainter( | 216 true, Painter::CreateSolidRoundRectPainter( |
| 152 theme->GetSystemColor( | 217 theme->GetSystemColor( |
| 153 ui::NativeTheme::kColorId_CallToActionColor), | 218 ui::NativeTheme::kColorId_CallToActionColor), |
| 154 kInkDropSmallCornerRadius)) | 219 kInkDropSmallCornerRadius)) |
| 155 : nullptr); | 220 : nullptr); |
| 156 } | 221 } |
| 157 | 222 |
| 158 } // namespace views | 223 } // namespace views |
| OLD | NEW |