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