• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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/menu_button.h"
6 
7 #include "base/strings/utf_string_conversions.h"
8 #include "ui/aura/test/event_generator.h"
9 #include "ui/aura/window.h"
10 #include "ui/views/controls/button/menu_button_listener.h"
11 #include "ui/views/test/views_test_base.h"
12 
13 using base::ASCIIToUTF16;
14 
15 namespace views {
16 
17 class MenuButtonTest : public ViewsTestBase {
18  public:
MenuButtonTest()19   MenuButtonTest() : widget_(NULL), button_(NULL) {}
~MenuButtonTest()20   virtual ~MenuButtonTest() {}
21 
TearDown()22   virtual void TearDown() OVERRIDE {
23     if (widget_ && !widget_->IsClosed())
24       widget_->Close();
25 
26     ViewsTestBase::TearDown();
27   }
28 
widget()29   Widget* widget() { return widget_; }
button()30   MenuButton* button() { return button_; }
31 
32  protected:
33   // Creates a MenuButton with a ButtonListener. In this case, the MenuButton
34   // acts like a regular button.
CreateMenuButtonWithButtonListener(ButtonListener * button_listener)35   void CreateMenuButtonWithButtonListener(ButtonListener* button_listener) {
36     CreateWidget();
37 
38     const base::string16 label(ASCIIToUTF16("button"));
39     button_ = new MenuButton(button_listener, label, NULL, false);
40     button_->SetBoundsRect(gfx::Rect(0, 0, 200, 20));
41     widget_->SetContentsView(button_);
42 
43     widget_->Show();
44   }
45 
46   // Creates a MenuButton with a MenuButtonListener. In this case, when the
47   // MenuButton is pushed, it notifies the MenuButtonListener to open a
48   // drop-down menu.
CreateMenuButtonWithMenuButtonListener(MenuButtonListener * menu_button_listener)49   void CreateMenuButtonWithMenuButtonListener(
50       MenuButtonListener* menu_button_listener) {
51     CreateWidget();
52 
53     const base::string16 label(ASCIIToUTF16("button"));
54     button_ = new MenuButton(NULL, label, menu_button_listener, false);
55     button_->SetBoundsRect(gfx::Rect(0, 0, 200, 20));
56     widget_->SetContentsView(button_);
57 
58     widget_->Show();
59   }
60 
61  private:
CreateWidget()62   void CreateWidget() {
63     DCHECK(!widget_);
64 
65     widget_ = new Widget;
66     Widget::InitParams params =
67         CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
68     params.bounds = gfx::Rect(0, 0, 200, 200);
69     widget_->Init(params);
70   }
71 
72   Widget* widget_;
73   MenuButton* button_;
74 };
75 
76 class TestButtonListener : public ButtonListener {
77  public:
TestButtonListener()78   TestButtonListener()
79       : last_sender_(NULL),
80         last_sender_state_(Button::STATE_NORMAL),
81         last_event_type_(ui::ET_UNKNOWN) {}
~TestButtonListener()82   virtual ~TestButtonListener() {}
83 
ButtonPressed(Button * sender,const ui::Event & event)84   virtual void ButtonPressed(Button* sender, const ui::Event& event) OVERRIDE {
85     last_sender_ = sender;
86     CustomButton* custom_button = CustomButton::AsCustomButton(sender);
87     DCHECK(custom_button);
88     last_sender_state_ = custom_button->state();
89     last_event_type_ = event.type();
90   }
91 
last_sender()92   Button* last_sender() { return last_sender_; }
last_sender_state()93   Button::ButtonState last_sender_state() { return last_sender_state_; }
last_event_type()94   ui::EventType last_event_type() { return last_event_type_; }
95 
96  private:
97   Button* last_sender_;
98   Button::ButtonState last_sender_state_;
99   ui::EventType last_event_type_;
100 
101   DISALLOW_COPY_AND_ASSIGN(TestButtonListener);
102 };
103 
104 class TestMenuButtonListener : public MenuButtonListener {
105  public:
TestMenuButtonListener()106   TestMenuButtonListener() {}
~TestMenuButtonListener()107   virtual ~TestMenuButtonListener() {}
108 
OnMenuButtonClicked(View * source,const gfx::Point &)109   virtual void OnMenuButtonClicked(View* source,
110                                    const gfx::Point& /*point*/) OVERRIDE {
111     last_source_ = source;
112     CustomButton* custom_button = CustomButton::AsCustomButton(source);
113     DCHECK(custom_button);
114     last_source_state_ = custom_button->state();
115   }
116 
last_source()117   View* last_source() { return last_source_; }
last_source_state()118   Button::ButtonState last_source_state() { return last_source_state_; }
119 
120  private:
121   View* last_source_;
122   Button::ButtonState last_source_state_;
123 };
124 
125 // Tests if the listener is notified correctly, when a mouse click happens on a
126 // MenuButton that has a regular ButtonListener.
TEST_F(MenuButtonTest,ActivateNonDropDownOnMouseClick)127 TEST_F(MenuButtonTest, ActivateNonDropDownOnMouseClick) {
128   scoped_ptr<TestButtonListener> button_listener(new TestButtonListener);
129   CreateMenuButtonWithButtonListener(button_listener.get());
130 
131   aura::test::EventGenerator generator(
132       widget()->GetNativeView()->GetRootWindow());
133 
134   generator.set_current_location(gfx::Point(10, 10));
135   generator.ClickLeftButton();
136 
137   // Check that MenuButton has notified the listener on mouse-released event,
138   // while it was in hovered state.
139   EXPECT_EQ(button(), button_listener->last_sender());
140   EXPECT_EQ(ui::ET_MOUSE_RELEASED, button_listener->last_event_type());
141   EXPECT_EQ(Button::STATE_HOVERED, button_listener->last_sender_state());
142 }
143 
144 // Tests if the listener is notified correctly when a gesture tap happens on a
145 // MenuButton that has a regular ButtonListener.
TEST_F(MenuButtonTest,ActivateNonDropDownOnGestureTap)146 TEST_F(MenuButtonTest, ActivateNonDropDownOnGestureTap) {
147   scoped_ptr<TestButtonListener> button_listener(new TestButtonListener);
148   CreateMenuButtonWithButtonListener(button_listener.get());
149 
150   aura::test::EventGenerator generator(
151       widget()->GetNativeView()->GetRootWindow());
152 
153   generator.GestureTapAt(gfx::Point(10, 10));
154 
155   // Check that MenuButton has notified the listener on gesture tap event, while
156   // it was in hovered state.
157   EXPECT_EQ(button(), button_listener->last_sender());
158   EXPECT_EQ(ui::ET_GESTURE_TAP, button_listener->last_event_type());
159   EXPECT_EQ(Button::STATE_HOVERED, button_listener->last_sender_state());
160 }
161 
162 // Tests if the listener is notified correctly when a mouse click happens on a
163 // MenuButton that has a MenuButtonListener.
TEST_F(MenuButtonTest,ActivateDropDownOnMouseClick)164 TEST_F(MenuButtonTest, ActivateDropDownOnMouseClick) {
165   scoped_ptr<TestMenuButtonListener> menu_button_listener(
166       new TestMenuButtonListener);
167   CreateMenuButtonWithMenuButtonListener(menu_button_listener.get());
168 
169   aura::test::EventGenerator generator(
170       widget()->GetNativeView()->GetRootWindow());
171 
172   generator.set_current_location(gfx::Point(10, 10));
173   generator.ClickLeftButton();
174 
175   // Check that MenuButton has notified the listener, while it was in pressed
176   // state.
177   EXPECT_EQ(button(), menu_button_listener->last_source());
178   EXPECT_EQ(Button::STATE_PRESSED, menu_button_listener->last_source_state());
179 }
180 
181 // Tests if the listener is notified correctly when a gesture tap happens on a
182 // MenuButton that has a MenuButtonListener.
TEST_F(MenuButtonTest,ActivateDropDownOnGestureTap)183 TEST_F(MenuButtonTest, ActivateDropDownOnGestureTap) {
184   scoped_ptr<TestMenuButtonListener> menu_button_listener(
185       new TestMenuButtonListener);
186   CreateMenuButtonWithMenuButtonListener(menu_button_listener.get());
187 
188   aura::test::EventGenerator generator(
189       widget()->GetNativeView()->GetRootWindow());
190 
191   generator.GestureTapAt(gfx::Point(10, 10));
192 
193   // Check that MenuButton has notified the listener, while it was in pressed
194   // state.
195   EXPECT_EQ(button(), menu_button_listener->last_source());
196   EXPECT_EQ(Button::STATE_PRESSED, menu_button_listener->last_source_state());
197 }
198 
199 }  // namespace views
200