Home | History | Annotate | Download | only in aura
      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 "ui/aura/window_targeter.h"
      6 
      7 #include "ui/aura/scoped_window_targeter.h"
      8 #include "ui/aura/test/aura_test_base.h"
      9 #include "ui/aura/test/test_window_delegate.h"
     10 #include "ui/aura/window.h"
     11 #include "ui/events/test/test_event_handler.h"
     12 
     13 namespace aura {
     14 
     15 // Always returns the same window.
     16 class StaticWindowTargeter : public ui::EventTargeter {
     17  public:
     18   explicit StaticWindowTargeter(aura::Window* window)
     19       : window_(window) {}
     20   virtual ~StaticWindowTargeter() {}
     21 
     22  private:
     23   // ui::EventTargeter:
     24   virtual ui::EventTarget* FindTargetForLocatedEvent(
     25       ui::EventTarget* root,
     26       ui::LocatedEvent* event) OVERRIDE {
     27     return window_;
     28   }
     29 
     30   Window* window_;
     31 
     32   DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter);
     33 };
     34 
     35 class WindowTargeterTest : public test::AuraTestBase {
     36  public:
     37   WindowTargeterTest() {}
     38   virtual ~WindowTargeterTest() {}
     39 
     40   Window* root_window() { return AuraTestBase::root_window(); }
     41 };
     42 
     43 gfx::RectF GetEffectiveVisibleBoundsInRootWindow(Window* window) {
     44   gfx::RectF bounds = gfx::Rect(window->bounds().size());
     45   Window* root = window->GetRootWindow();
     46   CHECK(window->layer());
     47   CHECK(root->layer());
     48   gfx::Transform transform;
     49   if (!window->layer()->GetTargetTransformRelativeTo(root->layer(), &transform))
     50     return gfx::RectF();
     51   transform.TransformRect(&bounds);
     52   return bounds;
     53 }
     54 
     55 TEST_F(WindowTargeterTest, Basic) {
     56   test::TestWindowDelegate delegate;
     57   scoped_ptr<Window> window(CreateNormalWindow(1, root_window(), &delegate));
     58   Window* one = CreateNormalWindow(2, window.get(), &delegate);
     59   Window* two = CreateNormalWindow(3, window.get(), &delegate);
     60 
     61   window->SetBounds(gfx::Rect(0, 0, 100, 100));
     62   one->SetBounds(gfx::Rect(0, 0, 500, 100));
     63   two->SetBounds(gfx::Rect(501, 0, 500, 1000));
     64 
     65   root_window()->Show();
     66 
     67   ui::test::TestEventHandler handler;
     68   one->AddPreTargetHandler(&handler);
     69 
     70   ui::MouseEvent press(ui::ET_MOUSE_PRESSED,
     71                        gfx::Point(20, 20),
     72                        gfx::Point(20, 20),
     73                        ui::EF_NONE,
     74                        ui::EF_NONE);
     75   DispatchEventUsingWindowDispatcher(&press);
     76   EXPECT_EQ(1, handler.num_mouse_events());
     77 
     78   handler.Reset();
     79   DispatchEventUsingWindowDispatcher(&press);
     80   EXPECT_EQ(1, handler.num_mouse_events());
     81 
     82   one->RemovePreTargetHandler(&handler);
     83 }
     84 
     85 TEST_F(WindowTargeterTest, ScopedWindowTargeter) {
     86   test::TestWindowDelegate delegate;
     87   scoped_ptr<Window> window(CreateNormalWindow(1, root_window(), &delegate));
     88   Window* child = CreateNormalWindow(2, window.get(), &delegate);
     89 
     90   window->SetBounds(gfx::Rect(30, 30, 100, 100));
     91   child->SetBounds(gfx::Rect(20, 20, 50, 50));
     92   root_window()->Show();
     93 
     94   ui::EventTarget* root = root_window();
     95   ui::EventTargeter* targeter = root->GetEventTargeter();
     96 
     97   gfx::Point event_location(60, 60);
     98   {
     99     ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
    100                          ui::EF_NONE, ui::EF_NONE);
    101     EXPECT_EQ(child, targeter->FindTargetForEvent(root, &mouse));
    102   }
    103 
    104   // Install a targeter on |window| so that the events never reach the child.
    105   scoped_ptr<ScopedWindowTargeter> scoped_targeter(
    106       new ScopedWindowTargeter(window.get(), scoped_ptr<ui::EventTargeter>(
    107           new StaticWindowTargeter(window.get()))));
    108   {
    109     ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
    110                          ui::EF_NONE, ui::EF_NONE);
    111     EXPECT_EQ(window.get(), targeter->FindTargetForEvent(root, &mouse));
    112   }
    113   scoped_targeter.reset();
    114   {
    115     ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
    116                          ui::EF_NONE, ui::EF_NONE);
    117     EXPECT_EQ(child, targeter->FindTargetForEvent(root, &mouse));
    118   }
    119 }
    120 
    121 TEST_F(WindowTargeterTest, TargetTransformedWindow) {
    122   root_window()->Show();
    123 
    124   test::TestWindowDelegate delegate;
    125   scoped_ptr<Window> window(CreateNormalWindow(2, root_window(), &delegate));
    126 
    127   const gfx::Rect window_bounds(100, 20, 400, 80);
    128   window->SetBounds(window_bounds);
    129 
    130   ui::EventTarget* root_target = root_window();
    131   ui::EventTargeter* targeter = root_target->GetEventTargeter();
    132   gfx::Point event_location(490, 50);
    133   {
    134     ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
    135                          ui::EF_NONE, ui::EF_NONE);
    136     EXPECT_EQ(window.get(), targeter->FindTargetForEvent(root_target, &mouse));
    137   }
    138 
    139   // Scale |window| by 50%. This should move it away from underneath
    140   // |event_location|, so an event in that location will not be targeted to it.
    141   gfx::Transform transform;
    142   transform.Scale(0.5, 0.5);
    143   window->SetTransform(transform);
    144   EXPECT_EQ(gfx::RectF(100, 20, 200, 40).ToString(),
    145             GetEffectiveVisibleBoundsInRootWindow(window.get()).ToString());
    146   {
    147     ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
    148                          ui::EF_NONE, ui::EF_NONE);
    149     EXPECT_EQ(root_window(), targeter->FindTargetForEvent(root_target, &mouse));
    150   }
    151 
    152   transform = gfx::Transform();
    153   transform.Translate(200, 10);
    154   transform.Scale(0.5, 0.5);
    155   window->SetTransform(transform);
    156   EXPECT_EQ(gfx::RectF(300, 30, 200, 40).ToString(),
    157             GetEffectiveVisibleBoundsInRootWindow(window.get()).ToString());
    158   {
    159     ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
    160                          ui::EF_NONE, ui::EF_NONE);
    161     EXPECT_EQ(window.get(), targeter->FindTargetForEvent(root_target, &mouse));
    162   }
    163 }
    164 
    165 }  // namespace aura
    166