Home | History | Annotate | Download | only in events
      1 // Copyright (c) 2013 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 "testing/gtest/include/gtest/gtest.h"
      6 #include "ui/events/event.h"
      7 #include "ui/events/event_targeter.h"
      8 #include "ui/events/test/test_event_processor.h"
      9 #include "ui/events/test/test_event_target.h"
     10 
     11 namespace ui {
     12 namespace test {
     13 
     14 class EventProcessorTest : public testing::Test {
     15  public:
     16   EventProcessorTest() {}
     17   virtual ~EventProcessorTest() {}
     18 
     19   // testing::Test:
     20   virtual void SetUp() OVERRIDE {
     21     processor_.SetRoot(scoped_ptr<EventTarget>(new TestEventTarget()));
     22     root()->SetEventTargeter(make_scoped_ptr(new EventTargeter()));
     23   }
     24 
     25   TestEventTarget* root() {
     26     return static_cast<TestEventTarget*>(processor_.GetRootTarget());
     27   }
     28 
     29   void DispatchEvent(Event* event) {
     30     processor_.OnEventFromSource(event);
     31   }
     32 
     33  protected:
     34   TestEventProcessor processor_;
     35 
     36   DISALLOW_COPY_AND_ASSIGN(EventProcessorTest);
     37 };
     38 
     39 TEST_F(EventProcessorTest, Basic) {
     40   scoped_ptr<TestEventTarget> child(new TestEventTarget());
     41   root()->AddChild(child.Pass());
     42 
     43   MouseEvent mouse(ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10),
     44                    EF_NONE);
     45   DispatchEvent(&mouse);
     46   EXPECT_TRUE(root()->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED));
     47   EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
     48 
     49   root()->RemoveChild(root()->child_at(0));
     50   DispatchEvent(&mouse);
     51   EXPECT_TRUE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
     52 }
     53 
     54 template<typename T>
     55 class BoundsEventTargeter : public EventTargeter {
     56  public:
     57   virtual ~BoundsEventTargeter() {}
     58 
     59  protected:
     60   virtual bool SubtreeShouldBeExploredForEvent(
     61       EventTarget* target, const LocatedEvent& event) OVERRIDE {
     62     T* t = static_cast<T*>(target);
     63     return (t->bounds().Contains(event.location()));
     64   }
     65 };
     66 
     67 class BoundsTestTarget : public TestEventTarget {
     68  public:
     69   BoundsTestTarget() {}
     70   virtual ~BoundsTestTarget() {}
     71 
     72   void set_bounds(gfx::Rect rect) { bounds_ = rect; }
     73   gfx::Rect bounds() const { return bounds_; }
     74 
     75   static void ConvertPointToTarget(BoundsTestTarget* source,
     76                                    BoundsTestTarget* target,
     77                                    gfx::Point* location) {
     78     gfx::Vector2d vector;
     79     if (source->Contains(target)) {
     80       for (; target && target != source;
     81            target = static_cast<BoundsTestTarget*>(target->parent())) {
     82         vector += target->bounds().OffsetFromOrigin();
     83       }
     84       *location -= vector;
     85     } else if (target->Contains(source)) {
     86       for (; source && source != target;
     87            source = static_cast<BoundsTestTarget*>(source->parent())) {
     88         vector += source->bounds().OffsetFromOrigin();
     89       }
     90       *location += vector;
     91     } else {
     92       NOTREACHED();
     93     }
     94   }
     95 
     96  private:
     97   // EventTarget:
     98   virtual void ConvertEventToTarget(EventTarget* target,
     99                                     LocatedEvent* event) OVERRIDE {
    100     event->ConvertLocationToTarget(this,
    101                                    static_cast<BoundsTestTarget*>(target));
    102   }
    103 
    104   gfx::Rect bounds_;
    105 
    106   DISALLOW_COPY_AND_ASSIGN(BoundsTestTarget);
    107 };
    108 
    109 TEST_F(EventProcessorTest, Bounds) {
    110   scoped_ptr<BoundsTestTarget> parent(new BoundsTestTarget());
    111   scoped_ptr<BoundsTestTarget> child(new BoundsTestTarget());
    112   scoped_ptr<BoundsTestTarget> grandchild(new BoundsTestTarget());
    113 
    114   parent->set_bounds(gfx::Rect(0, 0, 30, 30));
    115   child->set_bounds(gfx::Rect(5, 5, 20, 20));
    116   grandchild->set_bounds(gfx::Rect(5, 5, 5, 5));
    117 
    118   child->AddChild(scoped_ptr<TestEventTarget>(grandchild.Pass()));
    119   parent->AddChild(scoped_ptr<TestEventTarget>(child.Pass()));
    120   root()->AddChild(scoped_ptr<TestEventTarget>(parent.Pass()));
    121 
    122   ASSERT_EQ(1u, root()->child_count());
    123   ASSERT_EQ(1u, root()->child_at(0)->child_count());
    124   ASSERT_EQ(1u, root()->child_at(0)->child_at(0)->child_count());
    125 
    126   TestEventTarget* parent_r = root()->child_at(0);
    127   TestEventTarget* child_r = parent_r->child_at(0);
    128   TestEventTarget* grandchild_r = child_r->child_at(0);
    129 
    130   // Dispatch a mouse event that falls on the parent, but not on the child. When
    131   // the default event-targeter used, the event will still reach |grandchild|,
    132   // because the default targeter does not look at the bounds.
    133   MouseEvent mouse(ET_MOUSE_MOVED, gfx::Point(1, 1), gfx::Point(1, 1), EF_NONE);
    134   DispatchEvent(&mouse);
    135   EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
    136   EXPECT_FALSE(parent_r->DidReceiveEvent(ET_MOUSE_MOVED));
    137   EXPECT_FALSE(child_r->DidReceiveEvent(ET_MOUSE_MOVED));
    138   EXPECT_TRUE(grandchild_r->DidReceiveEvent(ET_MOUSE_MOVED));
    139   grandchild_r->ResetReceivedEvents();
    140 
    141   // Now install a targeter on the parent that looks at the bounds and makes
    142   // sure the event reaches the target only if the location of the event within
    143   // the bounds of the target.
    144   parent_r->SetEventTargeter(scoped_ptr<EventTargeter>(
    145       new BoundsEventTargeter<BoundsTestTarget>()));
    146   DispatchEvent(&mouse);
    147   EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
    148   EXPECT_TRUE(parent_r->DidReceiveEvent(ET_MOUSE_MOVED));
    149   EXPECT_FALSE(child_r->DidReceiveEvent(ET_MOUSE_MOVED));
    150   EXPECT_FALSE(grandchild_r->DidReceiveEvent(ET_MOUSE_MOVED));
    151   parent_r->ResetReceivedEvents();
    152 
    153   MouseEvent second(ET_MOUSE_MOVED, gfx::Point(12, 12), gfx::Point(12, 12),
    154                     EF_NONE);
    155   DispatchEvent(&second);
    156   EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
    157   EXPECT_FALSE(parent_r->DidReceiveEvent(ET_MOUSE_MOVED));
    158   EXPECT_FALSE(child_r->DidReceiveEvent(ET_MOUSE_MOVED));
    159   EXPECT_TRUE(grandchild_r->DidReceiveEvent(ET_MOUSE_MOVED));
    160 }
    161 
    162 }  // namespace test
    163 }  // namespace ui
    164