diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-21 21:13:19 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-21 21:13:19 +0000 |
commit | 2d0bd352bba817a6311cc58ed09083741f262841 (patch) | |
tree | effe12bf12c3f7cdeb5d1fe7ba88ce2ffee7f7ae | |
parent | 2e11765ef682220b05d2cd16e5b92d09dde86de0 (diff) | |
download | chromium_src-2d0bd352bba817a6311cc58ed09083741f262841.zip chromium_src-2d0bd352bba817a6311cc58ed09083741f262841.tar.gz chromium_src-2d0bd352bba817a6311cc58ed09083741f262841.tar.bz2 |
Add support for MouseEnter/MouseExit event types to be sent to aura::Windows.
BUG=none
TEST=see unittest
Review URL: http://codereview.chromium.org/7983039
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102168 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ui/aura/event.cc | 8 | ||||
-rw-r--r-- | ui/aura/event.h | 5 | ||||
-rw-r--r-- | ui/aura/root_window.cc | 40 | ||||
-rw-r--r-- | ui/aura/root_window.h | 5 | ||||
-rw-r--r-- | ui/aura/window_unittest.cc | 60 |
5 files changed, 114 insertions, 4 deletions
diff --git a/ui/aura/event.cc b/ui/aura/event.cc index ee79fce..6846f2e 100644 --- a/ui/aura/event.cc +++ b/ui/aura/event.cc @@ -49,6 +49,14 @@ MouseEvent::MouseEvent(const MouseEvent& model, Window* source, Window* target) : LocatedEvent(model, source, target) { } +MouseEvent::MouseEvent(const MouseEvent& model, + Window* source, + Window* target, + ui::EventType type) + : LocatedEvent(model, source, target) { + set_type(type); +} + MouseEvent::MouseEvent(ui::EventType type, const gfx::Point& location, int flags) diff --git a/ui/aura/event.h b/ui/aura/event.h index ed3a938..3560805 100644 --- a/ui/aura/event.h +++ b/ui/aura/event.h @@ -38,6 +38,7 @@ class AURA_EXPORT Event { Event(ui::EventType type, int flags); Event(NativeEvent native_event, ui::EventType type, int flags); Event(const Event& copy); + void set_type(ui::EventType type) { type_ = type; } private: void operator=(const Event&); @@ -83,6 +84,10 @@ class AURA_EXPORT MouseEvent : public LocatedEvent { // If source / target windows are provided, the model location will be // converted from |source| coordinate system to |target| coordinate system. MouseEvent(const MouseEvent& model, Window* source, Window* target); + MouseEvent(const MouseEvent& model, + Window* source, + Window* target, + ui::EventType type); // Used for synthetic events in testing. MouseEvent(ui::EventType type, const gfx::Point& location, int flags); diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc index f4b0c29..a528636 100644 --- a/ui/aura/root_window.cc +++ b/ui/aura/root_window.cc @@ -17,6 +17,7 @@ namespace internal { RootWindow::RootWindow() : Window(NULL), mouse_pressed_handler_(NULL), + mouse_moved_handler_(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(focus_manager_(new FocusManager(this))), capture_window_(NULL) { set_name(ASCIIToUTF16("RootWindow")); @@ -30,10 +31,20 @@ bool RootWindow::HandleMouseEvent(const MouseEvent& event) { mouse_pressed_handler_ ? mouse_pressed_handler_ : capture_window_; if (!target) target = GetEventHandlerForPoint(event.location()); - if (event.type() == ui::ET_MOUSE_PRESSED && !mouse_pressed_handler_) - mouse_pressed_handler_ = target; - if (event.type() == ui::ET_MOUSE_RELEASED) - mouse_pressed_handler_ = NULL; + switch (event.type()) { + case ui::ET_MOUSE_MOVED: + HandleMouseMoved(event, target); + break; + case ui::ET_MOUSE_PRESSED: + if (!mouse_pressed_handler_) + mouse_pressed_handler_ = target; + break; + case ui::ET_MOUSE_RELEASED: + mouse_pressed_handler_ = NULL; + break; + default: + break; + } if (target && target->delegate()) { MouseEvent translated_event(event, this, target); return target->OnMouseEvent(&translated_event); @@ -85,6 +96,8 @@ void RootWindow::WindowDestroying(Window* window) { // don't sent it release/capture lost events. if (mouse_pressed_handler_ == window) mouse_pressed_handler_ = NULL; + if (mouse_moved_handler_ == window) + mouse_moved_handler_ = NULL; if (capture_window_ == window) capture_window_ = NULL; } @@ -97,5 +110,24 @@ internal::RootWindow* RootWindow::GetRoot() { return this; } +void RootWindow::HandleMouseMoved(const MouseEvent& event, Window* target) { + if (target == mouse_moved_handler_) + return; + + // Send an exited event. + if (mouse_moved_handler_ && mouse_moved_handler_->delegate()) { + MouseEvent translated_event(event, this, mouse_moved_handler_, + ui::ET_MOUSE_EXITED); + mouse_moved_handler_->OnMouseEvent(&translated_event); + } + mouse_moved_handler_ = target; + // Send an entered event. + if (mouse_moved_handler_ && mouse_moved_handler_->delegate()) { + MouseEvent translated_event(event, this, mouse_moved_handler_, + ui::ET_MOUSE_ENTERED); + mouse_moved_handler_->OnMouseEvent(&translated_event); + } +} + } // namespace internal } // namespace aura diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h index 5d3de84..b3bf0e0 100644 --- a/ui/aura/root_window.h +++ b/ui/aura/root_window.h @@ -50,7 +50,12 @@ class RootWindow : public Window { virtual internal::RootWindow* GetRoot() OVERRIDE; private: + // Called whenever the mouse moves, tracks the current |mouse_moved_handler_|, + // sending exited and entered events as its value changes. + void HandleMouseMoved(const MouseEvent& event, Window* target); + Window* mouse_pressed_handler_; + Window* mouse_moved_handler_; scoped_ptr<FocusManager> focus_manager_; Window* capture_window_; diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc index 59d5dd1..6109145 100644 --- a/ui/aura/window_unittest.cc +++ b/ui/aura/window_unittest.cc @@ -385,5 +385,65 @@ TEST_F(WindowTest, ReleaseCaptureOnDestroy) { EXPECT_EQ(NULL, root->capture_window()); } +class MouseEnterExitWindowDelegate : public WindowDelegateImpl { + public: + MouseEnterExitWindowDelegate() : entered_(false), exited_(false) {} + + virtual bool OnMouseEvent(MouseEvent* event) OVERRIDE { + switch (event->type()) { + case ui::ET_MOUSE_ENTERED: + entered_ = true; + break; + case ui::ET_MOUSE_EXITED: + exited_ = true; + break; + default: + break; + } + return false; + } + + bool entered() const { return entered_; } + bool exited() const { return exited_; } + + private: + bool entered_; + bool exited_; + + DISALLOW_COPY_AND_ASSIGN(MouseEnterExitWindowDelegate); +}; + + +// Verifies that the WindowDelegate receives MouseExit and MouseEnter events for +// mouse transitions from window to window. +TEST_F(WindowTest, MouseEnterExit) { + Desktop* desktop = Desktop::GetInstance(); + + MouseEnterExitWindowDelegate d1; + scoped_ptr<Window> w1( + CreateTestWindowWithDelegate(&d1, 1, gfx::Rect(10, 10, 50, 50), NULL)); + MouseEnterExitWindowDelegate d2; + scoped_ptr<Window> w2( + CreateTestWindowWithDelegate(&d2, 2, gfx::Rect(70, 70, 50, 50), NULL)); + + gfx::Point move_point = w1->bounds().CenterPoint(); + Window::ConvertPointToWindow(w1->parent(), desktop->window(), &move_point); + desktop->OnMouseEvent(MouseEvent(ui::ET_MOUSE_MOVED, move_point, 0)); + + EXPECT_TRUE(d1.entered()); + EXPECT_FALSE(d1.exited()); + EXPECT_FALSE(d2.entered()); + EXPECT_FALSE(d2.exited()); + + move_point = w2->bounds().CenterPoint(); + Window::ConvertPointToWindow(w2->parent(), desktop->window(), &move_point); + desktop->OnMouseEvent(MouseEvent(ui::ET_MOUSE_MOVED, move_point, 0)); + + EXPECT_TRUE(d1.entered()); + EXPECT_TRUE(d1.exited()); + EXPECT_TRUE(d2.entered()); + EXPECT_FALSE(d2.exited()); +} + } // namespace internal } // namespace aura |