| OLD | NEW |
| 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/button/custom_button.h" | 5 #include "ui/views/controls/button/custom_button.h" |
| 6 | 6 |
| 7 #include "ui/accessibility/ax_view_state.h" | 7 #include "ui/accessibility/ax_view_state.h" |
| 8 #include "ui/base/material_design/material_design_controller.h" | 8 #include "ui/base/material_design/material_design_controller.h" |
| 9 #include "ui/events/event.h" | 9 #include "ui/events/event.h" |
| 10 #include "ui/events/event_utils.h" | 10 #include "ui/events/event_utils.h" |
| 11 #include "ui/events/keycodes/keyboard_codes.h" | 11 #include "ui/events/keycodes/keyboard_codes.h" |
| 12 #include "ui/gfx/animation/throb_animation.h" | 12 #include "ui/gfx/animation/throb_animation.h" |
| 13 #include "ui/gfx/canvas.h" | |
| 14 #include "ui/gfx/color_palette.h" | 13 #include "ui/gfx/color_palette.h" |
| 15 #include "ui/native_theme/native_theme.h" | 14 #include "ui/native_theme/native_theme.h" |
| 16 #include "ui/views/animation/ink_drop_delegate.h" | 15 #include "ui/views/animation/ink_drop_delegate.h" |
| 17 #include "ui/views/animation/ink_drop_hover.h" | 16 #include "ui/views/animation/ink_drop_hover.h" |
| 18 #include "ui/views/controls/button/blue_button.h" | 17 #include "ui/views/controls/button/blue_button.h" |
| 19 #include "ui/views/controls/button/checkbox.h" | 18 #include "ui/views/controls/button/checkbox.h" |
| 20 #include "ui/views/controls/button/image_button.h" | 19 #include "ui/views/controls/button/image_button.h" |
| 21 #include "ui/views/controls/button/label_button.h" | 20 #include "ui/views/controls/button/label_button.h" |
| 22 #include "ui/views/controls/button/menu_button.h" | 21 #include "ui/views/controls/button/menu_button.h" |
| 23 #include "ui/views/controls/button/radio_button.h" | 22 #include "ui/views/controls/button/radio_button.h" |
| 24 #include "ui/views/widget/widget.h" | 23 #include "ui/views/widget/widget.h" |
| 25 | 24 |
| 26 #if defined(USE_AURA) | 25 #if defined(USE_AURA) |
| 27 #include "ui/aura/client/capture_client.h" | 26 #include "ui/aura/client/capture_client.h" |
| 28 #include "ui/aura/window.h" | 27 #include "ui/aura/window.h" |
| 29 #endif | 28 #endif |
| 30 | 29 |
| 31 namespace views { | 30 namespace views { |
| 32 | 31 |
| 33 namespace { | 32 namespace { |
| 34 | 33 |
| 35 // How long the hover animation takes if uninterrupted. | 34 // How long the hover animation takes if uninterrupted. |
| 36 const int kHoverFadeDurationMs = 150; | 35 const int kHoverFadeDurationMs = 150; |
| 37 | 36 |
| 38 // The amount to enlarge the focus border in all directions relative to the | |
| 39 // button. | |
| 40 const int kFocusBorderOutset = -2; | |
| 41 | |
| 42 // The corner radius of the focus border roundrect. | |
| 43 const int kFocusBorderCornerRadius = 3; | |
| 44 | |
| 45 class MdFocusRing : public views::View { | |
| 46 public: | |
| 47 MdFocusRing() { | |
| 48 SetPaintToLayer(true); | |
| 49 layer()->SetFillsBoundsOpaquely(false); | |
| 50 } | |
| 51 ~MdFocusRing() override {} | |
| 52 | |
| 53 bool CanProcessEventsWithinSubtree() const override { | |
| 54 return false; | |
| 55 } | |
| 56 | |
| 57 void OnPaint(gfx::Canvas* canvas) override { | |
| 58 CustomButton::PaintMdFocusRing(canvas, this); | |
| 59 } | |
| 60 | |
| 61 private: | |
| 62 DISALLOW_COPY_AND_ASSIGN(MdFocusRing); | |
| 63 }; | |
| 64 | |
| 65 } // namespace | 37 } // namespace |
| 66 | 38 |
| 67 //////////////////////////////////////////////////////////////////////////////// | 39 //////////////////////////////////////////////////////////////////////////////// |
| 68 // CustomButton, public: | 40 // CustomButton, public: |
| 69 | 41 |
| 70 // static | 42 // static |
| 71 const char CustomButton::kViewClassName[] = "CustomButton"; | 43 const char CustomButton::kViewClassName[] = "CustomButton"; |
| 72 | 44 |
| 73 // static | 45 // static |
| 74 const CustomButton* CustomButton::AsCustomButton(const views::View* view) { | 46 const CustomButton* CustomButton::AsCustomButton(const views::View* view) { |
| 75 return AsCustomButton(const_cast<View*>(view)); | 47 return AsCustomButton(const_cast<View*>(view)); |
| 76 } | 48 } |
| 77 | 49 |
| 78 // static | 50 // static |
| 79 CustomButton* CustomButton::AsCustomButton(views::View* view) { | 51 CustomButton* CustomButton::AsCustomButton(views::View* view) { |
| 80 if (view) { | 52 if (view) { |
| 81 const char* classname = view->GetClassName(); | 53 const char* classname = view->GetClassName(); |
| 82 if (!strcmp(classname, Checkbox::kViewClassName) || | 54 if (!strcmp(classname, Checkbox::kViewClassName) || |
| 83 !strcmp(classname, CustomButton::kViewClassName) || | 55 !strcmp(classname, CustomButton::kViewClassName) || |
| 84 !strcmp(classname, ImageButton::kViewClassName) || | 56 !strcmp(classname, ImageButton::kViewClassName) || |
| 85 !strcmp(classname, LabelButton::kViewClassName) || | 57 !strcmp(classname, LabelButton::kViewClassName) || |
| 86 !strcmp(classname, RadioButton::kViewClassName) || | 58 !strcmp(classname, RadioButton::kViewClassName) || |
| 87 !strcmp(classname, MenuButton::kViewClassName)) { | 59 !strcmp(classname, MenuButton::kViewClassName)) { |
| 88 return static_cast<CustomButton*>(view); | 60 return static_cast<CustomButton*>(view); |
| 89 } | 61 } |
| 90 } | 62 } |
| 91 return NULL; | 63 return NULL; |
| 92 } | 64 } |
| 93 | 65 |
| 94 // static | |
| 95 void CustomButton::PaintMdFocusRing(gfx::Canvas* canvas, views::View* view) { | |
| 96 SkPaint paint; | |
| 97 paint.setAntiAlias(true); | |
| 98 paint.setColor(view->GetNativeTheme()->GetSystemColor( | |
| 99 ui::NativeTheme::kColorId_CallToActionColor)); | |
| 100 paint.setStyle(SkPaint::kStroke_Style); | |
| 101 paint.setStrokeWidth(1); | |
| 102 gfx::RectF rect(view->GetLocalBounds()); | |
| 103 rect.Inset(gfx::InsetsF(0.5)); | |
| 104 canvas->DrawRoundRect(rect, kFocusBorderCornerRadius, paint); | |
| 105 } | |
| 106 | |
| 107 CustomButton::~CustomButton() {} | 66 CustomButton::~CustomButton() {} |
| 108 | 67 |
| 109 void CustomButton::SetState(ButtonState state) { | 68 void CustomButton::SetState(ButtonState state) { |
| 110 if (state == state_) | 69 if (state == state_) |
| 111 return; | 70 return; |
| 112 | 71 |
| 113 if (animate_on_state_change_ && | 72 if (animate_on_state_change_ && |
| 114 (!is_throbbing_ || !hover_animation_.is_animating())) { | 73 (!is_throbbing_ || !hover_animation_.is_animating())) { |
| 115 is_throbbing_ = false; | 74 is_throbbing_ = false; |
| 116 if ((state_ == STATE_HOVERED) && (state == STATE_NORMAL)) { | 75 if ((state_ == STATE_HOVERED) && (state == STATE_NORMAL)) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 // TODO(bruthig): Is there any reason we are not calling | 128 // TODO(bruthig): Is there any reason we are not calling |
| 170 // Button::OnEnabledChanged() here? | 129 // Button::OnEnabledChanged() here? |
| 171 if (enabled() ? (state_ != STATE_DISABLED) : (state_ == STATE_DISABLED)) | 130 if (enabled() ? (state_ != STATE_DISABLED) : (state_ == STATE_DISABLED)) |
| 172 return; | 131 return; |
| 173 | 132 |
| 174 if (enabled()) | 133 if (enabled()) |
| 175 SetState(ShouldEnterHoveredState() ? STATE_HOVERED : STATE_NORMAL); | 134 SetState(ShouldEnterHoveredState() ? STATE_HOVERED : STATE_NORMAL); |
| 176 else | 135 else |
| 177 SetState(STATE_DISABLED); | 136 SetState(STATE_DISABLED); |
| 178 | 137 |
| 179 if (ink_drop_delegate_) | 138 if (ink_drop_delegate()) |
| 180 ink_drop_delegate_->SetHovered(ShouldShowInkDropHover()); | 139 ink_drop_delegate()->SetHovered(ShouldShowInkDropHover()); |
| 181 } | 140 } |
| 182 | 141 |
| 183 const char* CustomButton::GetClassName() const { | 142 const char* CustomButton::GetClassName() const { |
| 184 return kViewClassName; | 143 return kViewClassName; |
| 185 } | 144 } |
| 186 | 145 |
| 187 bool CustomButton::OnMousePressed(const ui::MouseEvent& event) { | 146 bool CustomButton::OnMousePressed(const ui::MouseEvent& event) { |
| 188 if (state_ == STATE_DISABLED) | 147 if (state_ == STATE_DISABLED) |
| 189 return true; | 148 return true; |
| 190 if (state_ != STATE_PRESSED && ShouldEnterPushedState(event) && | 149 if (state_ != STATE_PRESSED && ShouldEnterPushedState(event) && |
| 191 HitTestPoint(event.location())) { | 150 HitTestPoint(event.location())) { |
| 192 SetState(STATE_PRESSED); | 151 SetState(STATE_PRESSED); |
| 193 if (ink_drop_delegate_) | 152 if (ink_drop_delegate()) |
| 194 ink_drop_delegate_->OnAction(views::InkDropState::ACTION_PENDING); | 153 ink_drop_delegate()->OnAction(views::InkDropState::ACTION_PENDING); |
| 195 } | 154 } |
| 196 if (request_focus_on_press_) | 155 if (request_focus_on_press_) |
| 197 RequestFocus(); | 156 RequestFocus(); |
| 198 if (IsTriggerableEvent(event) && notify_action_ == NOTIFY_ON_PRESS) { | 157 if (IsTriggerableEvent(event) && notify_action_ == NOTIFY_ON_PRESS) { |
| 199 NotifyClick(event); | 158 NotifyClick(event); |
| 200 // NOTE: We may be deleted at this point (by the listener's notification | 159 // NOTE: We may be deleted at this point (by the listener's notification |
| 201 // handler). | 160 // handler). |
| 202 } | 161 } |
| 203 return true; | 162 return true; |
| 204 } | 163 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 232 } | 191 } |
| 233 | 192 |
| 234 void CustomButton::OnMouseCaptureLost() { | 193 void CustomButton::OnMouseCaptureLost() { |
| 235 // Starting a drag results in a MouseCaptureLost. Reset button state. | 194 // Starting a drag results in a MouseCaptureLost. Reset button state. |
| 236 // TODO(varkha) While in drag only reset the state with Material Design. | 195 // TODO(varkha) While in drag only reset the state with Material Design. |
| 237 // The same logic may applies everywhere so gather any feedback and update. | 196 // The same logic may applies everywhere so gather any feedback and update. |
| 238 bool reset_button_state = | 197 bool reset_button_state = |
| 239 !InDrag() || ui::MaterialDesignController::IsModeMaterial(); | 198 !InDrag() || ui::MaterialDesignController::IsModeMaterial(); |
| 240 if (state_ != STATE_DISABLED && reset_button_state) | 199 if (state_ != STATE_DISABLED && reset_button_state) |
| 241 SetState(STATE_NORMAL); | 200 SetState(STATE_NORMAL); |
| 242 if (ink_drop_delegate_) | 201 if (ink_drop_delegate()) |
| 243 ink_drop_delegate_->OnAction(views::InkDropState::HIDDEN); | 202 ink_drop_delegate()->OnAction(views::InkDropState::HIDDEN); |
| 244 } | 203 } |
| 245 | 204 |
| 246 void CustomButton::OnMouseEntered(const ui::MouseEvent& event) { | 205 void CustomButton::OnMouseEntered(const ui::MouseEvent& event) { |
| 247 if (state_ != STATE_DISABLED) | 206 if (state_ != STATE_DISABLED) |
| 248 SetState(STATE_HOVERED); | 207 SetState(STATE_HOVERED); |
| 249 } | 208 } |
| 250 | 209 |
| 251 void CustomButton::OnMouseExited(const ui::MouseEvent& event) { | 210 void CustomButton::OnMouseExited(const ui::MouseEvent& event) { |
| 252 // Starting a drag results in a MouseExited, we need to ignore it. | 211 // Starting a drag results in a MouseExited, we need to ignore it. |
| 253 if (state_ != STATE_DISABLED && !InDrag()) | 212 if (state_ != STATE_DISABLED && !InDrag()) |
| 254 SetState(STATE_NORMAL); | 213 SetState(STATE_NORMAL); |
| 255 } | 214 } |
| 256 | 215 |
| 257 void CustomButton::OnMouseMoved(const ui::MouseEvent& event) { | 216 void CustomButton::OnMouseMoved(const ui::MouseEvent& event) { |
| 258 if (state_ != STATE_DISABLED) | 217 if (state_ != STATE_DISABLED) |
| 259 SetState(HitTestPoint(event.location()) ? STATE_HOVERED : STATE_NORMAL); | 218 SetState(HitTestPoint(event.location()) ? STATE_HOVERED : STATE_NORMAL); |
| 260 } | 219 } |
| 261 | 220 |
| 262 bool CustomButton::OnKeyPressed(const ui::KeyEvent& event) { | 221 bool CustomButton::OnKeyPressed(const ui::KeyEvent& event) { |
| 263 if (state_ == STATE_DISABLED) | 222 if (state_ == STATE_DISABLED) |
| 264 return false; | 223 return false; |
| 265 | 224 |
| 266 // Space sets button state to pushed. Enter clicks the button. This matches | 225 // Space sets button state to pushed. Enter clicks the button. This matches |
| 267 // the Windows native behavior of buttons, where Space clicks the button on | 226 // the Windows native behavior of buttons, where Space clicks the button on |
| 268 // KeyRelease and Enter clicks the button on KeyPressed. | 227 // KeyRelease and Enter clicks the button on KeyPressed. |
| 269 if (event.key_code() == ui::VKEY_SPACE) { | 228 if (event.key_code() == ui::VKEY_SPACE) { |
| 270 SetState(STATE_PRESSED); | 229 SetState(STATE_PRESSED); |
| 271 if (ink_drop_delegate_ && | 230 if (ink_drop_delegate() && |
| 272 ink_drop_delegate_->GetTargetInkDropState() != | 231 ink_drop_delegate()->GetTargetInkDropState() != |
| 273 views::InkDropState::ACTION_PENDING) | 232 views::InkDropState::ACTION_PENDING) |
| 274 ink_drop_delegate_->OnAction(views::InkDropState::ACTION_PENDING); | 233 ink_drop_delegate()->OnAction(views::InkDropState::ACTION_PENDING); |
| 275 } else if (event.key_code() == ui::VKEY_RETURN) { | 234 } else if (event.key_code() == ui::VKEY_RETURN) { |
| 276 SetState(STATE_NORMAL); | 235 SetState(STATE_NORMAL); |
| 277 NotifyClick(event); | 236 NotifyClick(event); |
| 278 } else { | 237 } else { |
| 279 return false; | 238 return false; |
| 280 } | 239 } |
| 281 return true; | 240 return true; |
| 282 } | 241 } |
| 283 | 242 |
| 284 bool CustomButton::OnKeyReleased(const ui::KeyEvent& event) { | 243 bool CustomButton::OnKeyReleased(const ui::KeyEvent& event) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 | 297 |
| 339 void CustomButton::ShowContextMenu(const gfx::Point& p, | 298 void CustomButton::ShowContextMenu(const gfx::Point& p, |
| 340 ui::MenuSourceType source_type) { | 299 ui::MenuSourceType source_type) { |
| 341 if (!context_menu_controller()) | 300 if (!context_menu_controller()) |
| 342 return; | 301 return; |
| 343 | 302 |
| 344 // We're about to show the context menu. Showing the context menu likely means | 303 // We're about to show the context menu. Showing the context menu likely means |
| 345 // we won't get a mouse exited and reset state. Reset it now to be sure. | 304 // we won't get a mouse exited and reset state. Reset it now to be sure. |
| 346 if (state_ != STATE_DISABLED) | 305 if (state_ != STATE_DISABLED) |
| 347 SetState(STATE_NORMAL); | 306 SetState(STATE_NORMAL); |
| 348 if (hide_ink_drop_when_showing_context_menu_ && ink_drop_delegate_) { | 307 if (hide_ink_drop_when_showing_context_menu_ && ink_drop_delegate()) { |
| 349 ink_drop_delegate_->SetHovered(false); | 308 ink_drop_delegate()->SetHovered(false); |
| 350 ink_drop_delegate_->OnAction(InkDropState::HIDDEN); | 309 ink_drop_delegate()->OnAction(InkDropState::HIDDEN); |
| 351 } | 310 } |
| 352 View::ShowContextMenu(p, source_type); | 311 View::ShowContextMenu(p, source_type); |
| 353 } | 312 } |
| 354 | 313 |
| 355 void CustomButton::OnDragDone() { | 314 void CustomButton::OnDragDone() { |
| 356 // Only reset the state to normal if the button isn't currently disabled | 315 // Only reset the state to normal if the button isn't currently disabled |
| 357 // (since disabled buttons may still be able to be dragged). | 316 // (since disabled buttons may still be able to be dragged). |
| 358 if (state_ != STATE_DISABLED) | 317 if (state_ != STATE_DISABLED) |
| 359 SetState(STATE_NORMAL); | 318 SetState(STATE_NORMAL); |
| 360 if (ink_drop_delegate_) | 319 if (ink_drop_delegate()) |
| 361 ink_drop_delegate_->OnAction(InkDropState::HIDDEN); | 320 ink_drop_delegate()->OnAction(InkDropState::HIDDEN); |
| 362 } | 321 } |
| 363 | 322 |
| 364 void CustomButton::GetAccessibleState(ui::AXViewState* state) { | 323 void CustomButton::GetAccessibleState(ui::AXViewState* state) { |
| 365 Button::GetAccessibleState(state); | 324 Button::GetAccessibleState(state); |
| 366 switch (state_) { | 325 switch (state_) { |
| 367 case STATE_HOVERED: | 326 case STATE_HOVERED: |
| 368 state->AddStateFlag(ui::AX_STATE_HOVERED); | 327 state->AddStateFlag(ui::AX_STATE_HOVERED); |
| 369 break; | 328 break; |
| 370 case STATE_PRESSED: | 329 case STATE_PRESSED: |
| 371 state->AddStateFlag(ui::AX_STATE_PRESSED); | 330 state->AddStateFlag(ui::AX_STATE_PRESSED); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 397 //////////////////////////////////////////////////////////////////////////////// | 356 //////////////////////////////////////////////////////////////////////////////// |
| 398 // CustomButton, gfx::AnimationDelegate implementation: | 357 // CustomButton, gfx::AnimationDelegate implementation: |
| 399 | 358 |
| 400 void CustomButton::AnimationProgressed(const gfx::Animation* animation) { | 359 void CustomButton::AnimationProgressed(const gfx::Animation* animation) { |
| 401 SchedulePaint(); | 360 SchedulePaint(); |
| 402 } | 361 } |
| 403 | 362 |
| 404 //////////////////////////////////////////////////////////////////////////////// | 363 //////////////////////////////////////////////////////////////////////////////// |
| 405 // CustomButton, View overrides (public): | 364 // CustomButton, View overrides (public): |
| 406 | 365 |
| 407 void CustomButton::Layout() { | |
| 408 Button::Layout(); | |
| 409 gfx::Rect focus_bounds = GetLocalBounds(); | |
| 410 focus_bounds.Inset(gfx::Insets(kFocusBorderOutset)); | |
| 411 if (md_focus_ring_) | |
| 412 md_focus_ring_->SetBoundsRect(focus_bounds); | |
| 413 } | |
| 414 | |
| 415 void CustomButton::ViewHierarchyChanged( | 366 void CustomButton::ViewHierarchyChanged( |
| 416 const ViewHierarchyChangedDetails& details) { | 367 const ViewHierarchyChangedDetails& details) { |
| 417 if (!details.is_add && state_ != STATE_DISABLED) | 368 if (!details.is_add && state_ != STATE_DISABLED) |
| 418 SetState(STATE_NORMAL); | 369 SetState(STATE_NORMAL); |
| 419 } | 370 } |
| 420 | 371 |
| 421 void CustomButton::OnFocus() { | |
| 422 Button::OnFocus(); | |
| 423 if (md_focus_ring_) | |
| 424 md_focus_ring_->SetVisible(true); | |
| 425 } | |
| 426 | |
| 427 void CustomButton::OnBlur() { | 372 void CustomButton::OnBlur() { |
| 428 Button::OnBlur(); | 373 Button::OnBlur(); |
| 429 if (IsHotTracked()) | 374 if (IsHotTracked()) |
| 430 SetState(STATE_NORMAL); | 375 SetState(STATE_NORMAL); |
| 431 if (md_focus_ring_) | 376 } |
| 432 md_focus_ring_->SetVisible(false); | 377 |
| 378 bool CustomButton::ShouldShowInkDropForFocus() const { |
| 379 return true; |
| 433 } | 380 } |
| 434 | 381 |
| 435 //////////////////////////////////////////////////////////////////////////////// | 382 //////////////////////////////////////////////////////////////////////////////// |
| 436 // CustomButton, protected: | 383 // CustomButton, protected: |
| 437 | 384 |
| 438 CustomButton::CustomButton(ButtonListener* listener) | 385 CustomButton::CustomButton(ButtonListener* listener) |
| 439 : Button(listener), | 386 : Button(listener), |
| 440 state_(STATE_NORMAL), | 387 state_(STATE_NORMAL), |
| 441 hover_animation_(this), | 388 hover_animation_(this), |
| 442 animate_on_state_change_(true), | 389 animate_on_state_change_(true), |
| 443 is_throbbing_(false), | 390 is_throbbing_(false), |
| 444 triggerable_event_flags_(ui::EF_LEFT_MOUSE_BUTTON), | 391 triggerable_event_flags_(ui::EF_LEFT_MOUSE_BUTTON), |
| 445 request_focus_on_press_(false), | 392 request_focus_on_press_(false), |
| 446 ink_drop_delegate_(nullptr), | |
| 447 notify_action_(NOTIFY_ON_RELEASE), | 393 notify_action_(NOTIFY_ON_RELEASE), |
| 448 has_ink_drop_action_on_click_(false), | 394 has_ink_drop_action_on_click_(false), |
| 449 ink_drop_action_on_click_(InkDropState::ACTION_TRIGGERED), | 395 ink_drop_action_on_click_(InkDropState::ACTION_TRIGGERED), |
| 450 hide_ink_drop_when_showing_context_menu_(true), | 396 hide_ink_drop_when_showing_context_menu_(true), |
| 451 ink_drop_base_color_(gfx::kPlaceholderColor), | 397 ink_drop_base_color_(gfx::kPlaceholderColor) { |
| 452 md_focus_ring_(nullptr) { | |
| 453 hover_animation_.SetSlideDuration(kHoverFadeDurationMs); | 398 hover_animation_.SetSlideDuration(kHoverFadeDurationMs); |
| 454 } | 399 } |
| 455 | 400 |
| 456 void CustomButton::StateChanged() { | 401 void CustomButton::StateChanged() { |
| 457 } | 402 } |
| 458 | 403 |
| 459 bool CustomButton::IsTriggerableEvent(const ui::Event& event) { | 404 bool CustomButton::IsTriggerableEvent(const ui::Event& event) { |
| 460 return event.type() == ui::ET_GESTURE_TAP_DOWN || | 405 return event.type() == ui::ET_GESTURE_TAP_DOWN || |
| 461 event.type() == ui::ET_GESTURE_TAP || | 406 event.type() == ui::ET_GESTURE_TAP || |
| 462 (event.IsMouseEvent() && | 407 (event.IsMouseEvent() && |
| 463 (triggerable_event_flags_ & event.flags()) != 0); | 408 (triggerable_event_flags_ & event.flags()) != 0); |
| 464 } | 409 } |
| 465 | 410 |
| 466 bool CustomButton::ShouldEnterPushedState(const ui::Event& event) { | 411 bool CustomButton::ShouldEnterPushedState(const ui::Event& event) { |
| 467 return IsTriggerableEvent(event); | 412 return IsTriggerableEvent(event); |
| 468 } | 413 } |
| 469 | 414 |
| 470 bool CustomButton::ShouldShowInkDropHover() const { | 415 bool CustomButton::ShouldShowInkDropHover() const { |
| 471 return enabled() && IsMouseHovered() && !InDrag(); | 416 return enabled() && !InDrag() && |
| 417 (IsMouseHovered() || (ShouldShowInkDropForFocus() && HasFocus())); |
| 472 } | 418 } |
| 473 | 419 |
| 474 bool CustomButton::ShouldEnterHoveredState() { | 420 bool CustomButton::ShouldEnterHoveredState() { |
| 475 if (!visible()) | 421 if (!visible()) |
| 476 return false; | 422 return false; |
| 477 | 423 |
| 478 bool check_mouse_position = true; | 424 bool check_mouse_position = true; |
| 479 #if defined(USE_AURA) | 425 #if defined(USE_AURA) |
| 480 // If another window has capture, we shouldn't check the current mouse | 426 // If another window has capture, we shouldn't check the current mouse |
| 481 // position because the button won't receive any mouse events - so if the | 427 // position because the button won't receive any mouse events - so if the |
| 482 // mouse was hovered, the button would be stuck in a hovered state (since it | 428 // mouse was hovered, the button would be stuck in a hovered state (since it |
| 483 // would never receive OnMouseExited). | 429 // would never receive OnMouseExited). |
| 484 const Widget* widget = GetWidget(); | 430 const Widget* widget = GetWidget(); |
| 485 if (widget && widget->GetNativeWindow()) { | 431 if (widget && widget->GetNativeWindow()) { |
| 486 aura::Window* root_window = widget->GetNativeWindow()->GetRootWindow(); | 432 aura::Window* root_window = widget->GetNativeWindow()->GetRootWindow(); |
| 487 aura::client::CaptureClient* capture_client = | 433 aura::client::CaptureClient* capture_client = |
| 488 aura::client::GetCaptureClient(root_window); | 434 aura::client::GetCaptureClient(root_window); |
| 489 aura::Window* capture_window = | 435 aura::Window* capture_window = |
| 490 capture_client ? capture_client->GetGlobalCaptureWindow() : nullptr; | 436 capture_client ? capture_client->GetGlobalCaptureWindow() : nullptr; |
| 491 check_mouse_position = !capture_window || capture_window == root_window; | 437 check_mouse_position = !capture_window || capture_window == root_window; |
| 492 } | 438 } |
| 493 #endif | 439 #endif |
| 494 | 440 |
| 495 return check_mouse_position && IsMouseHovered(); | 441 return check_mouse_position && IsMouseHovered(); |
| 496 } | 442 } |
| 497 | 443 |
| 498 void CustomButton::UseMdFocusRing() { | |
| 499 DCHECK(!md_focus_ring_); | |
| 500 md_focus_ring_ = new MdFocusRing(); | |
| 501 AddChildView(md_focus_ring_); | |
| 502 md_focus_ring_->SetVisible(false); | |
| 503 set_request_focus_on_press(false); | |
| 504 } | |
| 505 | |
| 506 //////////////////////////////////////////////////////////////////////////////// | 444 //////////////////////////////////////////////////////////////////////////////// |
| 507 // CustomButton, Button overrides (protected): | 445 // CustomButton, Button overrides (protected): |
| 508 | 446 |
| 509 void CustomButton::NotifyClick(const ui::Event& event) { | 447 void CustomButton::NotifyClick(const ui::Event& event) { |
| 510 if (ink_drop_delegate() && has_ink_drop_action_on_click_) | 448 if (ink_drop_delegate() && has_ink_drop_action_on_click_) |
| 511 ink_drop_delegate()->OnAction(ink_drop_action_on_click_); | 449 ink_drop_delegate()->OnAction(ink_drop_action_on_click_); |
| 512 Button::NotifyClick(event); | 450 Button::NotifyClick(event); |
| 513 } | 451 } |
| 514 | 452 |
| 515 void CustomButton::OnClickCanceled(const ui::Event& event) { | 453 void CustomButton::OnClickCanceled(const ui::Event& event) { |
| 516 if (ink_drop_delegate()) | 454 if (ink_drop_delegate()) |
| 517 ink_drop_delegate()->OnAction(views::InkDropState::HIDDEN); | 455 ink_drop_delegate()->OnAction(views::InkDropState::HIDDEN); |
| 518 Button::OnClickCanceled(event); | 456 Button::OnClickCanceled(event); |
| 519 } | 457 } |
| 520 | 458 |
| 521 } // namespace views | 459 } // namespace views |
| OLD | NEW |