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.
5 #include "ui/views/controls/button/custom_button.h"
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/events/event_utils.h"
13 #include "ui/gfx/screen.h"
14 #include "ui/views/controls/button/checkbox.h"
15 #include "ui/views/controls/button/image_button.h"
16 #include "ui/views/controls/button/label_button.h"
17 #include "ui/views/controls/button/menu_button.h"
18 #include "ui/views/controls/button/radio_button.h"
19 #include "ui/views/controls/link.h"
20 #include "ui/views/controls/textfield/textfield.h"
21 #include "ui/views/test/views_test_base.h"
27 class TestCustomButton
: public CustomButton
, public ButtonListener
{
29 explicit TestCustomButton()
30 : CustomButton(this) {
33 ~TestCustomButton() override
{}
35 void ButtonPressed(Button
* sender
, const ui::Event
& event
) override
{
39 bool notified() { return notified_
; }
41 void Reset() { notified_
= false; }
44 bool notified_
= false;
46 DISALLOW_COPY_AND_ASSIGN(TestCustomButton
);
49 void PerformGesture(CustomButton
* button
, ui::EventType event_type
) {
50 ui::GestureEventDetails
gesture_details(event_type
);
51 base::TimeDelta time_stamp
= base::TimeDelta::FromMicroseconds(0);
52 ui::GestureEvent
gesture_event(0, 0, 0, time_stamp
, gesture_details
);
53 button
->OnGestureEvent(&gesture_event
);
56 class CustomButtonTest
: public ViewsTestBase
{
59 ~CustomButtonTest() override
{}
61 void SetUp() override
{
62 ViewsTestBase::SetUp();
64 // Create a widget so that the CustomButton can query the hover state
66 widget_
.reset(new Widget
);
67 Widget::InitParams params
= CreateParams(Widget::InitParams::TYPE_POPUP
);
68 params
.ownership
= views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
69 params
.bounds
= gfx::Rect(0, 0, 650, 650);
70 widget_
->Init(params
);
73 // Position the widget in a way so that it is under the cursor.
74 gfx::Point cursor
= gfx::Screen::GetScreenFor(
75 widget_
->GetNativeView())->GetCursorScreenPoint();
76 gfx::Rect widget_bounds
= widget_
->GetWindowBoundsInScreen();
77 widget_bounds
.set_origin(cursor
);
78 widget_
->SetBounds(widget_bounds
);
80 button_
= new TestCustomButton();
81 widget_
->SetContentsView(button_
);
84 Widget
* widget() { return widget_
.get(); }
85 TestCustomButton
* button() { return button_
; }
88 scoped_ptr
<Widget
> widget_
;
89 TestCustomButton
* button_
;
91 DISALLOW_COPY_AND_ASSIGN(CustomButtonTest
);
96 // Tests that hover state changes correctly when visiblity/enableness changes.
97 TEST_F(CustomButtonTest
, HoverStateOnVisibilityChange
) {
98 aura::test::TestCursorClient
cursor_client(
99 widget()->GetNativeView()->GetRootWindow());
101 gfx::Point
center(10, 10);
102 button()->OnMousePressed(ui::MouseEvent(
103 ui::ET_MOUSE_PRESSED
, center
, center
, ui::EventTimeForNow(),
104 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
));
105 EXPECT_EQ(CustomButton::STATE_PRESSED
, button()->state());
107 button()->OnMouseReleased(ui::MouseEvent(
108 ui::ET_MOUSE_RELEASED
, center
, center
, ui::EventTimeForNow(),
109 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
));
110 EXPECT_EQ(CustomButton::STATE_HOVERED
, button()->state());
112 button()->SetEnabled(false);
113 EXPECT_EQ(CustomButton::STATE_DISABLED
, button()->state());
115 button()->SetEnabled(true);
116 EXPECT_EQ(CustomButton::STATE_HOVERED
, button()->state());
118 button()->SetVisible(false);
119 EXPECT_EQ(CustomButton::STATE_NORMAL
, button()->state());
121 button()->SetVisible(true);
122 EXPECT_EQ(CustomButton::STATE_HOVERED
, button()->state());
124 // In Aura views, no new hover effects are invoked if mouse events
126 cursor_client
.DisableMouseEvents();
128 button()->SetEnabled(false);
129 EXPECT_EQ(CustomButton::STATE_DISABLED
, button()->state());
131 button()->SetEnabled(true);
132 EXPECT_EQ(CustomButton::STATE_NORMAL
, button()->state());
134 button()->SetVisible(false);
135 EXPECT_EQ(CustomButton::STATE_NORMAL
, button()->state());
137 button()->SetVisible(true);
138 EXPECT_EQ(CustomButton::STATE_NORMAL
, button()->state());
141 // Tests the different types of NotifyActions.
142 TEST_F(CustomButtonTest
, NotifyAction
) {
143 gfx::Point
center(10, 10);
145 // By default the button should notify its listener on mouse release.
146 button()->OnMousePressed(ui::MouseEvent(
147 ui::ET_MOUSE_PRESSED
, center
, center
, ui::EventTimeForNow(),
148 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
));
149 EXPECT_EQ(CustomButton::STATE_PRESSED
, button()->state());
150 EXPECT_FALSE(button()->notified());
152 button()->OnMouseReleased(ui::MouseEvent(
153 ui::ET_MOUSE_RELEASED
, center
, center
, ui::EventTimeForNow(),
154 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
));
155 EXPECT_EQ(CustomButton::STATE_HOVERED
, button()->state());
156 EXPECT_TRUE(button()->notified());
158 // Set the notify action to its listener on mouse press.
160 button()->set_notify_action(CustomButton::NOTIFY_ON_PRESS
);
161 button()->OnMousePressed(ui::MouseEvent(
162 ui::ET_MOUSE_PRESSED
, center
, center
, ui::EventTimeForNow(),
163 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
));
164 EXPECT_EQ(CustomButton::STATE_PRESSED
, button()->state());
165 EXPECT_TRUE(button()->notified());
167 // The button should no longer notify on mouse release.
169 button()->OnMouseReleased(ui::MouseEvent(
170 ui::ET_MOUSE_RELEASED
, center
, center
, ui::EventTimeForNow(),
171 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
));
172 EXPECT_EQ(CustomButton::STATE_HOVERED
, button()->state());
173 EXPECT_FALSE(button()->notified());
176 // Tests that gesture events correctly change the button state.
177 TEST_F(CustomButtonTest
, GestureEventsSetState
) {
178 aura::test::TestCursorClient
cursor_client(
179 widget()->GetNativeView()->GetRootWindow());
181 EXPECT_EQ(CustomButton::STATE_NORMAL
, button()->state());
183 PerformGesture(button(), ui::ET_GESTURE_TAP_DOWN
);
184 EXPECT_EQ(CustomButton::STATE_PRESSED
, button()->state());
186 PerformGesture(button(), ui::ET_GESTURE_SHOW_PRESS
);
187 EXPECT_EQ(CustomButton::STATE_PRESSED
, button()->state());
189 PerformGesture(button(), ui::ET_GESTURE_TAP_CANCEL
);
190 EXPECT_EQ(CustomButton::STATE_NORMAL
, button()->state());
193 // Ensure subclasses of CustomButton are correctly recognized as CustomButton.
194 TEST_F(CustomButtonTest
, AsCustomButton
) {
197 LabelButton
label_button(NULL
, text
);
198 EXPECT_TRUE(CustomButton::AsCustomButton(&label_button
));
200 ImageButton
image_button(NULL
);
201 EXPECT_TRUE(CustomButton::AsCustomButton(&image_button
));
203 Checkbox
checkbox(text
);
204 EXPECT_TRUE(CustomButton::AsCustomButton(&checkbox
));
206 RadioButton
radio_button(text
, 0);
207 EXPECT_TRUE(CustomButton::AsCustomButton(&radio_button
));
209 MenuButton
menu_button(NULL
, text
, NULL
, false);
210 EXPECT_TRUE(CustomButton::AsCustomButton(&menu_button
));
213 EXPECT_FALSE(CustomButton::AsCustomButton(&label
));
216 EXPECT_FALSE(CustomButton::AsCustomButton(&link
));
219 EXPECT_FALSE(CustomButton::AsCustomButton(&textfield
));