| 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 "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "build/build_config.h" | 8 #include "build/build_config.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 #include "ui/base/layout.h" | 10 #include "ui/base/layout.h" |
| 11 #include "ui/base/material_design/material_design_controller.h" | 11 #include "ui/base/material_design/material_design_controller.h" |
| 12 #include "ui/events/event_utils.h" | 12 #include "ui/events/event_utils.h" |
| 13 #include "ui/events/test/event_generator.h" | 13 #include "ui/events/test/event_generator.h" |
| 14 #include "ui/gfx/screen.h" | 14 #include "ui/gfx/screen.h" |
| 15 #include "ui/views/animation/ink_drop_delegate.h" | 15 #include "ui/views/animation/ink_drop_delegate.h" |
| 16 #include "ui/views/animation/ink_drop_host.h" | 16 #include "ui/views/animation/ink_drop_host.h" |
| 17 #include "ui/views/animation/test/test_ink_drop_delegate.h" |
| 17 #include "ui/views/animation/test/test_ink_drop_host.h" | 18 #include "ui/views/animation/test/test_ink_drop_host.h" |
| 19 #include "ui/views/context_menu_controller.h" |
| 18 #include "ui/views/controls/button/checkbox.h" | 20 #include "ui/views/controls/button/checkbox.h" |
| 19 #include "ui/views/controls/button/image_button.h" | 21 #include "ui/views/controls/button/image_button.h" |
| 20 #include "ui/views/controls/button/label_button.h" | 22 #include "ui/views/controls/button/label_button.h" |
| 21 #include "ui/views/controls/button/menu_button.h" | 23 #include "ui/views/controls/button/menu_button.h" |
| 22 #include "ui/views/controls/button/radio_button.h" | 24 #include "ui/views/controls/button/radio_button.h" |
| 23 #include "ui/views/controls/link.h" | 25 #include "ui/views/controls/link.h" |
| 24 #include "ui/views/controls/textfield/textfield.h" | 26 #include "ui/views/controls/textfield/textfield.h" |
| 25 #include "ui/views/test/views_test_base.h" | 27 #include "ui/views/test/views_test_base.h" |
| 26 | 28 |
| 27 #if defined(USE_AURA) | 29 #if defined(USE_AURA) |
| 28 #include "ui/aura/test/test_cursor_client.h" | 30 #include "ui/aura/test/test_cursor_client.h" |
| 29 #include "ui/aura/window.h" | 31 #include "ui/aura/window.h" |
| 30 #include "ui/aura/window_event_dispatcher.h" | 32 #include "ui/aura/window_event_dispatcher.h" |
| 31 #endif | 33 #endif |
| 32 | 34 |
| 33 namespace views { | 35 namespace views { |
| 34 | 36 |
| 37 using test::TestInkDropDelegate; |
| 38 |
| 35 namespace { | 39 namespace { |
| 36 | 40 |
| 41 // No-op test double of a ContextMenuController. |
| 42 class TestContextMenuController : public ContextMenuController { |
| 43 public: |
| 44 TestContextMenuController() {} |
| 45 ~TestContextMenuController() override {} |
| 46 |
| 47 // ContextMenuController: |
| 48 void ShowContextMenuForView(View* source, |
| 49 const gfx::Point& point, |
| 50 ui::MenuSourceType source_type) override {} |
| 51 |
| 52 private: |
| 53 DISALLOW_COPY_AND_ASSIGN(TestContextMenuController); |
| 54 }; |
| 55 |
| 37 class TestCustomButton : public CustomButton, public ButtonListener { | 56 class TestCustomButton : public CustomButton, public ButtonListener { |
| 38 public: | 57 public: |
| 39 explicit TestCustomButton() | 58 explicit TestCustomButton() |
| 40 : CustomButton(this) { | 59 : CustomButton(this) { |
| 41 } | 60 } |
| 42 | 61 |
| 43 ~TestCustomButton() override {} | 62 ~TestCustomButton() override {} |
| 44 | 63 |
| 45 void ButtonPressed(Button* sender, const ui::Event& event) override { | 64 void ButtonPressed(Button* sender, const ui::Event& event) override { |
| 46 pressed_ = true; | 65 pressed_ = true; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 59 } | 78 } |
| 60 | 79 |
| 61 private: | 80 private: |
| 62 bool pressed_ = false; | 81 bool pressed_ = false; |
| 63 bool canceled_ = false; | 82 bool canceled_ = false; |
| 64 | 83 |
| 65 DISALLOW_COPY_AND_ASSIGN(TestCustomButton); | 84 DISALLOW_COPY_AND_ASSIGN(TestCustomButton); |
| 66 }; | 85 }; |
| 67 | 86 |
| 68 // An InkDropDelegate that keeps track of ink drop visibility. | 87 // An InkDropDelegate that keeps track of ink drop visibility. |
| 69 class TestInkDropDelegate : public InkDropDelegate { | 88 class TestInkDropDelegateThatTracksVisibilty : public InkDropDelegate { |
| 70 public: | 89 public: |
| 71 TestInkDropDelegate(InkDropHost* ink_drop_host, | 90 TestInkDropDelegateThatTracksVisibilty(bool* ink_shown, bool* ink_hidden) |
| 72 bool* ink_shown, | 91 : ink_shown_(ink_shown), ink_hidden_(ink_hidden) {} |
| 73 bool* ink_hidden) | 92 ~TestInkDropDelegateThatTracksVisibilty() override {} |
| 74 : ink_drop_host_(ink_drop_host), | |
| 75 ink_shown_(ink_shown), | |
| 76 ink_hidden_(ink_hidden) {} | |
| 77 ~TestInkDropDelegate() override {} | |
| 78 | 93 |
| 79 // InkDropDelegate: | 94 // InkDropDelegate: |
| 80 void OnAction(InkDropState state) override { | 95 void OnAction(InkDropState state) override { |
| 81 switch (state) { | 96 switch (state) { |
| 82 case InkDropState::ACTION_PENDING: | 97 case InkDropState::ACTION_PENDING: |
| 83 case InkDropState::SLOW_ACTION_PENDING: | 98 case InkDropState::SLOW_ACTION_PENDING: |
| 84 case InkDropState::ACTIVATED: | 99 case InkDropState::ACTIVATED: |
| 85 *ink_shown_ = true; | 100 *ink_shown_ = true; |
| 86 break; | 101 break; |
| 87 case InkDropState::HIDDEN: | 102 case InkDropState::HIDDEN: |
| 88 *ink_hidden_ = true; | 103 *ink_hidden_ = true; |
| 89 break; | 104 break; |
| 90 case InkDropState::QUICK_ACTION: | 105 case InkDropState::QUICK_ACTION: |
| 91 case InkDropState::SLOW_ACTION: | 106 case InkDropState::SLOW_ACTION: |
| 92 case InkDropState::DEACTIVATED: | 107 case InkDropState::DEACTIVATED: |
| 93 break; | 108 break; |
| 94 } | 109 } |
| 95 } | 110 } |
| 96 | 111 |
| 112 void SnapToActivated() override { *ink_shown_ = true; } |
| 113 |
| 97 void SetHovered(bool is_hovered) override {} | 114 void SetHovered(bool is_hovered) override {} |
| 98 | 115 |
| 99 private: | 116 private: |
| 100 InkDropHost* ink_drop_host_; | |
| 101 bool* ink_shown_; | 117 bool* ink_shown_; |
| 102 bool* ink_hidden_; | 118 bool* ink_hidden_; |
| 103 | 119 |
| 104 DISALLOW_COPY_AND_ASSIGN(TestInkDropDelegate); | 120 DISALLOW_COPY_AND_ASSIGN(TestInkDropDelegateThatTracksVisibilty); |
| 105 }; | 121 }; |
| 106 | 122 |
| 107 // A test Button class that owns a TestInkDropDelegate. | 123 // A test Button class that owns a TestInkDropDelegate. |
| 108 class TestButtonWithInkDrop : public TestCustomButton { | 124 class TestButtonWithInkDrop : public TestCustomButton { |
| 109 public: | 125 public: |
| 110 TestButtonWithInkDrop(bool* ink_shown, bool* ink_hidden) | 126 TestButtonWithInkDrop(scoped_ptr<InkDropDelegate> ink_drop_delegate) |
| 111 : TestCustomButton(), | 127 : TestCustomButton(), ink_drop_delegate_(std::move(ink_drop_delegate)) { |
| 112 ink_drop_delegate_( | |
| 113 new TestInkDropDelegate(this, ink_shown, ink_hidden)) { | |
| 114 set_ink_drop_delegate(ink_drop_delegate_.get()); | 128 set_ink_drop_delegate(ink_drop_delegate_.get()); |
| 115 } | 129 } |
| 116 ~TestButtonWithInkDrop() override {} | 130 ~TestButtonWithInkDrop() override {} |
| 117 | 131 |
| 118 private: | 132 private: |
| 119 scoped_ptr<views::InkDropDelegate> ink_drop_delegate_; | 133 scoped_ptr<views::InkDropDelegate> ink_drop_delegate_; |
| 120 | 134 |
| 121 DISALLOW_COPY_AND_ASSIGN(TestButtonWithInkDrop); | 135 DISALLOW_COPY_AND_ASSIGN(TestButtonWithInkDrop); |
| 122 }; | 136 }; |
| 123 | 137 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 142 | 156 |
| 143 button_ = new TestCustomButton(); | 157 button_ = new TestCustomButton(); |
| 144 widget_->SetContentsView(button_); | 158 widget_->SetContentsView(button_); |
| 145 } | 159 } |
| 146 | 160 |
| 147 void TearDown() override { | 161 void TearDown() override { |
| 148 widget_.reset(); | 162 widget_.reset(); |
| 149 ViewsTestBase::TearDown(); | 163 ViewsTestBase::TearDown(); |
| 150 } | 164 } |
| 151 | 165 |
| 152 void CreateButtonWithInkDrop() { | 166 void CreateButtonWithInkDrop(scoped_ptr<InkDropDelegate> ink_drop_delegate) { |
| 153 delete button_; | 167 delete button_; |
| 154 ink_shown_ = false; | 168 button_ = new TestButtonWithInkDrop(std::move(ink_drop_delegate)); |
| 155 ink_hidden_ = false; | |
| 156 button_ = new TestButtonWithInkDrop(&ink_shown_, &ink_hidden_); | |
| 157 widget_->SetContentsView(button_); | 169 widget_->SetContentsView(button_); |
| 158 } | 170 } |
| 159 | 171 |
| 160 protected: | 172 protected: |
| 161 Widget* widget() { return widget_.get(); } | 173 Widget* widget() { return widget_.get(); } |
| 162 TestCustomButton* button() { return button_; } | 174 TestCustomButton* button() { return button_; } |
| 163 bool ink_shown() const { return ink_shown_; } | |
| 164 bool ink_hidden() const { return ink_hidden_; } | |
| 165 void SetDraggedView(View* dragged_view) { | 175 void SetDraggedView(View* dragged_view) { |
| 166 widget_->dragged_view_ = dragged_view; | 176 widget_->dragged_view_ = dragged_view; |
| 167 } | 177 } |
| 168 | 178 |
| 169 private: | 179 private: |
| 170 scoped_ptr<Widget> widget_; | 180 scoped_ptr<Widget> widget_; |
| 171 TestCustomButton* button_; | 181 TestCustomButton* button_; |
| 172 bool ink_shown_ = false; | |
| 173 bool ink_hidden_ = false; | |
| 174 | 182 |
| 175 DISALLOW_COPY_AND_ASSIGN(CustomButtonTest); | 183 DISALLOW_COPY_AND_ASSIGN(CustomButtonTest); |
| 176 }; | 184 }; |
| 177 | 185 |
| 178 // Tests that hover state changes correctly when visiblity/enableness changes. | 186 // Tests that hover state changes correctly when visiblity/enableness changes. |
| 179 TEST_F(CustomButtonTest, HoverStateOnVisibilityChange) { | 187 TEST_F(CustomButtonTest, HoverStateOnVisibilityChange) { |
| 180 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow()); | 188 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow()); |
| 181 | 189 |
| 182 generator.PressLeftButton(); | 190 generator.PressLeftButton(); |
| 183 EXPECT_EQ(CustomButton::STATE_PRESSED, button()->state()); | 191 EXPECT_EQ(CustomButton::STATE_PRESSED, button()->state()); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 Textfield textfield; | 384 Textfield textfield; |
| 377 EXPECT_FALSE(CustomButton::AsCustomButton(&textfield)); | 385 EXPECT_FALSE(CustomButton::AsCustomButton(&textfield)); |
| 378 } | 386 } |
| 379 | 387 |
| 380 // Tests that pressing a button shows the ink drop and releasing the button | 388 // Tests that pressing a button shows the ink drop and releasing the button |
| 381 // does not hide the ink drop. | 389 // does not hide the ink drop. |
| 382 // Note: Ink drop is not hidden upon release because CustomButton descendants | 390 // Note: Ink drop is not hidden upon release because CustomButton descendants |
| 383 // may enter a different ink drop state. | 391 // may enter a different ink drop state. |
| 384 TEST_F(CustomButtonTest, ButtonClickTogglesInkDrop) { | 392 TEST_F(CustomButtonTest, ButtonClickTogglesInkDrop) { |
| 385 gfx::Point old_cursor = gfx::Screen::GetScreen()->GetCursorScreenPoint(); | 393 gfx::Point old_cursor = gfx::Screen::GetScreen()->GetCursorScreenPoint(); |
| 386 CreateButtonWithInkDrop(); | 394 bool ink_shown = false; |
| 395 bool ink_hidden = false; |
| 396 CreateButtonWithInkDrop(make_scoped_ptr( |
| 397 new TestInkDropDelegateThatTracksVisibilty(&ink_shown, &ink_hidden))); |
| 387 | 398 |
| 388 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow()); | 399 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow()); |
| 389 generator.set_current_location(gfx::Point(50, 50)); | 400 generator.set_current_location(gfx::Point(50, 50)); |
| 390 generator.PressLeftButton(); | 401 generator.PressLeftButton(); |
| 391 EXPECT_TRUE(ink_shown()); | 402 EXPECT_TRUE(ink_shown); |
| 392 EXPECT_FALSE(ink_hidden()); | 403 EXPECT_FALSE(ink_hidden); |
| 393 | 404 |
| 394 generator.ReleaseLeftButton(); | 405 generator.ReleaseLeftButton(); |
| 395 EXPECT_FALSE(ink_hidden()); | 406 EXPECT_FALSE(ink_hidden); |
| 396 } | 407 } |
| 397 | 408 |
| 398 // Tests that pressing a button shows and releasing capture hides ink drop. | 409 // Tests that pressing a button shows and releasing capture hides ink drop. |
| 399 // Releasing capture should also reset PRESSED button state to NORMAL. | 410 // Releasing capture should also reset PRESSED button state to NORMAL. |
| 400 TEST_F(CustomButtonTest, CaptureLossHidesInkDrop) { | 411 TEST_F(CustomButtonTest, CaptureLossHidesInkDrop) { |
| 401 gfx::Point old_cursor = gfx::Screen::GetScreen()->GetCursorScreenPoint(); | 412 gfx::Point old_cursor = gfx::Screen::GetScreen()->GetCursorScreenPoint(); |
| 402 CreateButtonWithInkDrop(); | 413 bool ink_shown = false; |
| 414 bool ink_hidden = false; |
| 415 CreateButtonWithInkDrop(make_scoped_ptr( |
| 416 new TestInkDropDelegateThatTracksVisibilty(&ink_shown, &ink_hidden))); |
| 403 | 417 |
| 404 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow()); | 418 ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow()); |
| 405 generator.set_current_location(gfx::Point(50, 50)); | 419 generator.set_current_location(gfx::Point(50, 50)); |
| 406 generator.PressLeftButton(); | 420 generator.PressLeftButton(); |
| 407 EXPECT_TRUE(ink_shown()); | 421 EXPECT_TRUE(ink_shown); |
| 408 EXPECT_FALSE(ink_hidden()); | 422 EXPECT_FALSE(ink_hidden); |
| 409 | 423 |
| 410 EXPECT_EQ(Button::ButtonState::STATE_PRESSED, button()->state()); | 424 EXPECT_EQ(Button::ButtonState::STATE_PRESSED, button()->state()); |
| 411 SetDraggedView(button()); | 425 SetDraggedView(button()); |
| 412 widget()->SetCapture(button()); | 426 widget()->SetCapture(button()); |
| 413 widget()->ReleaseCapture(); | 427 widget()->ReleaseCapture(); |
| 414 SetDraggedView(nullptr); | 428 SetDraggedView(nullptr); |
| 415 EXPECT_TRUE(ink_hidden()); | 429 EXPECT_TRUE(ink_hidden); |
| 416 EXPECT_EQ(ui::MaterialDesignController::IsModeMaterial() | 430 EXPECT_EQ(ui::MaterialDesignController::IsModeMaterial() |
| 417 ? Button::ButtonState::STATE_NORMAL | 431 ? Button::ButtonState::STATE_NORMAL |
| 418 : Button::ButtonState::STATE_PRESSED, | 432 : Button::ButtonState::STATE_PRESSED, |
| 419 button()->state()); | 433 button()->state()); |
| 420 } | 434 } |
| 421 | 435 |
| 436 TEST_F(CustomButtonTest, InkDropAfterShowingContextMenu) { |
| 437 TestInkDropDelegate* ink_drop_delegate = new TestInkDropDelegate(); |
| 438 CreateButtonWithInkDrop(make_scoped_ptr(ink_drop_delegate)); |
| 439 TestContextMenuController context_menu_controller; |
| 440 button()->set_context_menu_controller(&context_menu_controller); |
| 441 |
| 442 ink_drop_delegate->SetHovered(true); |
| 443 ink_drop_delegate->OnAction(InkDropState::ACTION_PENDING); |
| 444 |
| 445 button()->ShowContextMenu(gfx::Point(), ui::MENU_SOURCE_MOUSE); |
| 446 |
| 447 EXPECT_FALSE(ink_drop_delegate->is_hovered()); |
| 448 EXPECT_EQ(InkDropState::HIDDEN, ink_drop_delegate->state()); |
| 449 } |
| 450 |
| 451 TEST_F(CustomButtonTest, InkDropAfterTryingToShowContextMenu) { |
| 452 TestInkDropDelegate* ink_drop_delegate = new TestInkDropDelegate(); |
| 453 CreateButtonWithInkDrop(make_scoped_ptr(ink_drop_delegate)); |
| 454 button()->set_context_menu_controller(nullptr); |
| 455 |
| 456 ink_drop_delegate->SetHovered(true); |
| 457 ink_drop_delegate->OnAction(InkDropState::ACTION_PENDING); |
| 458 |
| 459 button()->ShowContextMenu(gfx::Point(), ui::MENU_SOURCE_MOUSE); |
| 460 |
| 461 EXPECT_TRUE(ink_drop_delegate->is_hovered()); |
| 462 EXPECT_EQ(InkDropState::ACTION_PENDING, ink_drop_delegate->state()); |
| 463 } |
| 464 |
| 422 } // namespace views | 465 } // namespace views |
| OLD | NEW |