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 3 // found in the LICENSE file. 4 5 #include "ui/views/controls/button/custom_button.h" 6 7 #include "testing/gtest/include/gtest/gtest.h" 8 #include "ui/aura/test/test_cursor_client.h" 9 #include "ui/aura/window.h" 10 #include "ui/aura/window_event_dispatcher.h" 11 #include "ui/base/layout.h" 12 #include "ui/gfx/screen.h" 13 #include "ui/views/controls/button/checkbox.h" 14 #include "ui/views/controls/button/image_button.h" 15 #include "ui/views/controls/button/label_button.h" 16 #include "ui/views/controls/button/menu_button.h" 17 #include "ui/views/controls/button/radio_button.h" 18 #include "ui/views/controls/link.h" 19 #include "ui/views/controls/textfield/textfield.h" 20 #include "ui/views/test/views_test_base.h" 21 22 namespace views { 23 24 namespace { 25 26 class TestCustomButton : public CustomButton { 27 public: 28 explicit TestCustomButton(ButtonListener* listener) 29 : CustomButton(listener) { 30 } 31 32 virtual ~TestCustomButton() {} 33 34 private: 35 DISALLOW_COPY_AND_ASSIGN(TestCustomButton); 36 }; 37 38 void PerformGesture(CustomButton* button, ui::EventType event_type) { 39 ui::GestureEventDetails gesture_details(event_type); 40 base::TimeDelta time_stamp = base::TimeDelta::FromMicroseconds(0); 41 ui::GestureEvent gesture_event(0, 0, 0, time_stamp, gesture_details); 42 button->OnGestureEvent(&gesture_event); 43 } 44 45 } // namespace 46 47 typedef ViewsTestBase CustomButtonTest; 48 49 // Tests that hover state changes correctly when visiblity/enableness changes. 50 TEST_F(CustomButtonTest, HoverStateOnVisibilityChange) { 51 // Create a widget so that the CustomButton can query the hover state 52 // correctly. 53 scoped_ptr<Widget> widget(new Widget); 54 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); 55 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 56 params.bounds = gfx::Rect(0, 0, 650, 650); 57 widget->Init(params); 58 widget->Show(); 59 60 aura::test::TestCursorClient cursor_client( 61 widget->GetNativeView()->GetRootWindow()); 62 63 // Position the widget in a way so that it is under the cursor. 64 gfx::Point cursor = gfx::Screen::GetScreenFor( 65 widget->GetNativeView())->GetCursorScreenPoint(); 66 gfx::Rect widget_bounds = widget->GetWindowBoundsInScreen(); 67 widget_bounds.set_origin(cursor); 68 widget->SetBounds(widget_bounds); 69 70 TestCustomButton* button = new TestCustomButton(NULL); 71 widget->SetContentsView(button); 72 73 gfx::Point center(10, 10); 74 button->OnMousePressed(ui::MouseEvent(ui::ET_MOUSE_PRESSED, center, center, 75 ui::EF_LEFT_MOUSE_BUTTON, 76 ui::EF_LEFT_MOUSE_BUTTON)); 77 EXPECT_EQ(CustomButton::STATE_PRESSED, button->state()); 78 79 button->OnMouseReleased(ui::MouseEvent(ui::ET_MOUSE_RELEASED, center, center, 80 ui::EF_LEFT_MOUSE_BUTTON, 81 ui::EF_LEFT_MOUSE_BUTTON)); 82 EXPECT_EQ(CustomButton::STATE_HOVERED, button->state()); 83 84 button->SetEnabled(false); 85 EXPECT_EQ(CustomButton::STATE_DISABLED, button->state()); 86 87 button->SetEnabled(true); 88 EXPECT_EQ(CustomButton::STATE_HOVERED, button->state()); 89 90 button->SetVisible(false); 91 EXPECT_EQ(CustomButton::STATE_NORMAL, button->state()); 92 93 button->SetVisible(true); 94 EXPECT_EQ(CustomButton::STATE_HOVERED, button->state()); 95 96 // In Aura views, no new hover effects are invoked if mouse events 97 // are disabled. 98 cursor_client.DisableMouseEvents(); 99 100 button->SetEnabled(false); 101 EXPECT_EQ(CustomButton::STATE_DISABLED, button->state()); 102 103 button->SetEnabled(true); 104 EXPECT_EQ(CustomButton::STATE_NORMAL, button->state()); 105 106 button->SetVisible(false); 107 EXPECT_EQ(CustomButton::STATE_NORMAL, button->state()); 108 109 button->SetVisible(true); 110 EXPECT_EQ(CustomButton::STATE_NORMAL, button->state()); 111 } 112 113 // Tests that gesture events correctly change the button state. 114 TEST_F(CustomButtonTest, GestureEventsSetState) { 115 // Create a widget so that the CustomButton can query the hover state 116 // correctly. 117 scoped_ptr<Widget> widget(new Widget); 118 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); 119 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 120 params.bounds = gfx::Rect(0, 0, 650, 650); 121 widget->Init(params); 122 widget->Show(); 123 124 aura::test::TestCursorClient cursor_client( 125 widget->GetNativeView()->GetRootWindow()); 126 127 TestCustomButton* button = new TestCustomButton(NULL); 128 widget->SetContentsView(button); 129 130 EXPECT_EQ(CustomButton::STATE_NORMAL, button->state()); 131 132 PerformGesture(button, ui::ET_GESTURE_TAP_DOWN); 133 EXPECT_EQ(CustomButton::STATE_PRESSED, button->state()); 134 135 PerformGesture(button, ui::ET_GESTURE_SHOW_PRESS); 136 EXPECT_EQ(CustomButton::STATE_PRESSED, button->state()); 137 138 PerformGesture(button, ui::ET_GESTURE_TAP_CANCEL); 139 EXPECT_EQ(CustomButton::STATE_NORMAL, button->state()); 140 } 141 142 // Ensure subclasses of CustomButton are correctly recognized as CustomButton. 143 TEST_F(CustomButtonTest, AsCustomButton) { 144 base::string16 text; 145 146 LabelButton label_button(NULL, text); 147 EXPECT_TRUE(CustomButton::AsCustomButton(&label_button)); 148 149 ImageButton image_button(NULL); 150 EXPECT_TRUE(CustomButton::AsCustomButton(&image_button)); 151 152 Checkbox checkbox(text); 153 EXPECT_TRUE(CustomButton::AsCustomButton(&checkbox)); 154 155 RadioButton radio_button(text, 0); 156 EXPECT_TRUE(CustomButton::AsCustomButton(&radio_button)); 157 158 MenuButton menu_button(NULL, text, NULL, false); 159 EXPECT_TRUE(CustomButton::AsCustomButton(&menu_button)); 160 161 Label label; 162 EXPECT_FALSE(CustomButton::AsCustomButton(&label)); 163 164 Link link(text); 165 EXPECT_FALSE(CustomButton::AsCustomButton(&link)); 166 167 Textfield textfield; 168 EXPECT_FALSE(CustomButton::AsCustomButton(&textfield)); 169 } 170 171 } // namespace views 172