| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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 "aura/desktop.h" | |
| 6 #include "aura/event.h" | |
| 7 #include "aura/focus_manager.h" | |
| 8 #include "aura/root_window.h" | |
| 9 #include "aura/window_delegate.h" | |
| 10 #include "base/basictypes.h" | |
| 11 #include "base/compiler_specific.h" | |
| 12 #include "base/message_loop.h" | |
| 13 #include "testing/gtest/include/gtest/gtest.h" | |
| 14 #include "ui/gfx/canvas_skia.h" | |
| 15 #include "ui/base/keycodes/keyboard_codes.h" | |
| 16 | |
| 17 #if !defined(OS_WIN) | |
| 18 #include "aura/hit_test.h" | |
| 19 #endif | |
| 20 | |
| 21 namespace aura { | |
| 22 namespace internal { | |
| 23 | |
| 24 namespace { | |
| 25 | |
| 26 // WindowDelegate implementation with all methods stubbed out. | |
| 27 class WindowDelegateImpl : public WindowDelegate { | |
| 28 public: | |
| 29 WindowDelegateImpl() {} | |
| 30 virtual ~WindowDelegateImpl() {} | |
| 31 | |
| 32 // Overriden from WindowDelegate: | |
| 33 virtual void OnFocus() OVERRIDE {} | |
| 34 virtual void OnBlur() OVERRIDE {} | |
| 35 virtual bool OnKeyEvent(KeyEvent* event) OVERRIDE { | |
| 36 return false; | |
| 37 } | |
| 38 virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE { | |
| 39 return HTCLIENT; | |
| 40 } | |
| 41 virtual bool OnMouseEvent(MouseEvent* event) OVERRIDE { return false; } | |
| 42 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {} | |
| 43 virtual void OnWindowDestroying() OVERRIDE {} | |
| 44 virtual void OnWindowDestroyed() OVERRIDE {} | |
| 45 | |
| 46 private: | |
| 47 DISALLOW_COPY_AND_ASSIGN(WindowDelegateImpl); | |
| 48 }; | |
| 49 | |
| 50 // Used for verifying destruction methods are invoked. | |
| 51 class DestroyTrackingDelegateImpl : public WindowDelegateImpl { | |
| 52 public: | |
| 53 DestroyTrackingDelegateImpl() | |
| 54 : destroying_count_(0), | |
| 55 destroyed_count_(0), | |
| 56 in_destroying_(false) {} | |
| 57 | |
| 58 void clear_destroying_count() { destroying_count_ = 0; } | |
| 59 int destroying_count() const { return destroying_count_; } | |
| 60 | |
| 61 void clear_destroyed_count() { destroyed_count_ = 0; } | |
| 62 int destroyed_count() const { return destroyed_count_; } | |
| 63 | |
| 64 bool in_destroying() const { return in_destroying_; } | |
| 65 | |
| 66 virtual void OnWindowDestroying() OVERRIDE { | |
| 67 EXPECT_FALSE(in_destroying_); | |
| 68 in_destroying_ = true; | |
| 69 destroying_count_++; | |
| 70 } | |
| 71 | |
| 72 virtual void OnWindowDestroyed() OVERRIDE { | |
| 73 EXPECT_TRUE(in_destroying_); | |
| 74 in_destroying_ = false; | |
| 75 destroyed_count_++; | |
| 76 } | |
| 77 | |
| 78 private: | |
| 79 bool in_destroying_; | |
| 80 int destroying_count_; | |
| 81 int destroyed_count_; | |
| 82 | |
| 83 DISALLOW_COPY_AND_ASSIGN(DestroyTrackingDelegateImpl); | |
| 84 }; | |
| 85 | |
| 86 // Used to verify that when OnWindowDestroying is invoked the parent is also | |
| 87 // is in the process of being destroyed. | |
| 88 class ChildWindowDelegateImpl : public DestroyTrackingDelegateImpl { | |
| 89 public: | |
| 90 explicit ChildWindowDelegateImpl( | |
| 91 DestroyTrackingDelegateImpl* parent_delegate) | |
| 92 : parent_delegate_(parent_delegate) { | |
| 93 } | |
| 94 | |
| 95 virtual void OnWindowDestroying() OVERRIDE { | |
| 96 EXPECT_TRUE(parent_delegate_->in_destroying()); | |
| 97 DestroyTrackingDelegateImpl::OnWindowDestroying(); | |
| 98 } | |
| 99 | |
| 100 private: | |
| 101 DestroyTrackingDelegateImpl* parent_delegate_; | |
| 102 | |
| 103 DISALLOW_COPY_AND_ASSIGN(ChildWindowDelegateImpl); | |
| 104 }; | |
| 105 | |
| 106 // A simple WindowDelegate implementation for these tests. It owns itself | |
| 107 // (deletes itself when the Window it is attached to is destroyed). | |
| 108 class TestWindowDelegate : public WindowDelegateImpl { | |
| 109 public: | |
| 110 TestWindowDelegate(SkColor color) | |
| 111 : color_(color), | |
| 112 last_key_code_(ui::VKEY_UNKNOWN) { | |
| 113 } | |
| 114 virtual ~TestWindowDelegate() {} | |
| 115 | |
| 116 ui::KeyboardCode last_key_code() const { return last_key_code_; } | |
| 117 | |
| 118 // Overridden from WindowDelegateImpl: | |
| 119 virtual bool OnKeyEvent(KeyEvent* event) OVERRIDE { | |
| 120 last_key_code_ = event->key_code(); | |
| 121 return true; | |
| 122 } | |
| 123 virtual void OnWindowDestroyed() OVERRIDE { | |
| 124 delete this; | |
| 125 } | |
| 126 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { | |
| 127 canvas->AsCanvasSkia()->drawColor(color_, SkXfermode::kSrc_Mode); | |
| 128 } | |
| 129 | |
| 130 private: | |
| 131 SkColor color_; | |
| 132 ui::KeyboardCode last_key_code_; | |
| 133 | |
| 134 DISALLOW_COPY_AND_ASSIGN(TestWindowDelegate); | |
| 135 }; | |
| 136 | |
| 137 class WindowTest : public testing::Test { | |
| 138 public: | |
| 139 WindowTest() : main_message_loop(MessageLoop::TYPE_UI) { | |
| 140 aura::Desktop::GetInstance()->Show(); | |
| 141 aura::Desktop::GetInstance()->SetSize(gfx::Size(500, 500)); | |
| 142 } | |
| 143 virtual ~WindowTest() {} | |
| 144 | |
| 145 // Overridden from testing::Test: | |
| 146 virtual void SetUp() OVERRIDE { | |
| 147 } | |
| 148 | |
| 149 virtual void TearDown() OVERRIDE { | |
| 150 } | |
| 151 | |
| 152 Window* CreateTestWindow(SkColor color, | |
| 153 int id, | |
| 154 const gfx::Rect& bounds, | |
| 155 Window* parent) { | |
| 156 return CreateTestWindowWithDelegate(new TestWindowDelegate(color), | |
| 157 id, bounds, parent); | |
| 158 } | |
| 159 | |
| 160 Window* CreateTestWindowWithDelegate(WindowDelegate* delegate, | |
| 161 int id, | |
| 162 const gfx::Rect& bounds, | |
| 163 Window* parent) { | |
| 164 Window* window = new Window(delegate); | |
| 165 window->set_id(id); | |
| 166 window->Init(); | |
| 167 window->SetBounds(bounds, 0); | |
| 168 window->SetVisibility(Window::VISIBILITY_SHOWN); | |
| 169 window->SetParent(parent); | |
| 170 return window; | |
| 171 } | |
| 172 | |
| 173 void RunPendingMessages() { | |
| 174 MessageLoop message_loop(MessageLoop::TYPE_UI); | |
| 175 MessageLoopForUI::current()->Run(NULL); | |
| 176 } | |
| 177 | |
| 178 private: | |
| 179 MessageLoop main_message_loop; | |
| 180 | |
| 181 DISALLOW_COPY_AND_ASSIGN(WindowTest); | |
| 182 }; | |
| 183 | |
| 184 } // namespace | |
| 185 | |
| 186 TEST_F(WindowTest, HitTest) { | |
| 187 Window w1(new TestWindowDelegate(SK_ColorWHITE)); | |
| 188 w1.set_id(1); | |
| 189 w1.Init(); | |
| 190 w1.SetBounds(gfx::Rect(10, 10, 50, 50), 0); | |
| 191 w1.SetVisibility(Window::VISIBILITY_SHOWN); | |
| 192 w1.SetParent(NULL); | |
| 193 | |
| 194 // Points are in the Window's coordinates. | |
| 195 EXPECT_TRUE(w1.HitTest(gfx::Point(1, 1))); | |
| 196 EXPECT_FALSE(w1.HitTest(gfx::Point(-1, -1))); | |
| 197 | |
| 198 // TODO(beng): clip Window to parent. | |
| 199 } | |
| 200 | |
| 201 TEST_F(WindowTest, GetEventHandlerForPoint) { | |
| 202 scoped_ptr<Window> w1( | |
| 203 CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500), NULL)); | |
| 204 scoped_ptr<Window> w11( | |
| 205 CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(5, 5, 100, 100), w1.get())); | |
| 206 scoped_ptr<Window> w111( | |
| 207 CreateTestWindow(SK_ColorCYAN, 111, gfx::Rect(5, 5, 75, 75), w11.get())); | |
| 208 scoped_ptr<Window> w1111( | |
| 209 CreateTestWindow(SK_ColorRED, 1111, gfx::Rect(5, 5, 50, 50), w111.get())); | |
| 210 scoped_ptr<Window> w12( | |
| 211 CreateTestWindow(SK_ColorMAGENTA, 12, gfx::Rect(10, 420, 25, 25), | |
| 212 w1.get())); | |
| 213 scoped_ptr<Window> w121( | |
| 214 CreateTestWindow(SK_ColorYELLOW, 121, gfx::Rect(5, 5, 5, 5), w12.get())); | |
| 215 scoped_ptr<Window> w13( | |
| 216 CreateTestWindow(SK_ColorGRAY, 13, gfx::Rect(5, 470, 50, 50), w1.get())); | |
| 217 | |
| 218 Window* desktop = Desktop::GetInstance()->window(); | |
| 219 EXPECT_EQ(desktop, desktop->GetEventHandlerForPoint(gfx::Point(5, 5))); | |
| 220 EXPECT_EQ(w1.get(), desktop->GetEventHandlerForPoint(gfx::Point(11, 11))); | |
| 221 EXPECT_EQ(w11.get(), desktop->GetEventHandlerForPoint(gfx::Point(16, 16))); | |
| 222 EXPECT_EQ(w111.get(), desktop->GetEventHandlerForPoint(gfx::Point(21, 21))); | |
| 223 EXPECT_EQ(w1111.get(), desktop->GetEventHandlerForPoint(gfx::Point(26, 26))); | |
| 224 EXPECT_EQ(w12.get(), desktop->GetEventHandlerForPoint(gfx::Point(21, 431))); | |
| 225 EXPECT_EQ(w121.get(), desktop->GetEventHandlerForPoint(gfx::Point(26, 436))); | |
| 226 EXPECT_EQ(w13.get(), desktop->GetEventHandlerForPoint(gfx::Point(26, 481))); | |
| 227 } | |
| 228 | |
| 229 TEST_F(WindowTest, Focus) { | |
| 230 scoped_ptr<Window> w1( | |
| 231 CreateTestWindow(SK_ColorWHITE, 1, gfx::Rect(10, 10, 500, 500), NULL)); | |
| 232 scoped_ptr<Window> w11( | |
| 233 CreateTestWindow(SK_ColorGREEN, 11, gfx::Rect(5, 5, 100, 100), w1.get())); | |
| 234 scoped_ptr<Window> w111( | |
| 235 CreateTestWindow(SK_ColorCYAN, 111, gfx::Rect(5, 5, 75, 75), w11.get())); | |
| 236 scoped_ptr<Window> w1111( | |
| 237 CreateTestWindow(SK_ColorRED, 1111, gfx::Rect(5, 5, 50, 50), w111.get())); | |
| 238 scoped_ptr<Window> w12( | |
| 239 CreateTestWindow(SK_ColorMAGENTA, 12, gfx::Rect(10, 420, 25, 25), | |
| 240 w1.get())); | |
| 241 TestWindowDelegate* w121delegate = new TestWindowDelegate(SK_ColorYELLOW); | |
| 242 scoped_ptr<Window> w121( | |
| 243 CreateTestWindowWithDelegate(w121delegate, 121, gfx::Rect(5, 5, 5, 5), | |
| 244 w12.get())); | |
| 245 scoped_ptr<Window> w13( | |
| 246 CreateTestWindow(SK_ColorGRAY, 13, gfx::Rect(5, 470, 50, 50), w1.get())); | |
| 247 | |
| 248 // Click on a sub-window (w121) to focus it. | |
| 249 Desktop* desktop = Desktop::GetInstance(); | |
| 250 gfx::Point click_point = w121->bounds().CenterPoint(); | |
| 251 Window::ConvertPointToWindow(w121->parent(), desktop->window(), &click_point); | |
| 252 desktop->OnMouseEvent( | |
| 253 MouseEvent(ui::ET_MOUSE_PRESSED, click_point, ui::EF_LEFT_BUTTON_DOWN)); | |
| 254 internal::FocusManager* focus_manager = w121->GetFocusManager(); | |
| 255 EXPECT_EQ(w121.get(), focus_manager->focused_window()); | |
| 256 | |
| 257 // The key press should be sent to the focused sub-window. | |
| 258 desktop->OnKeyEvent(KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_E, 0)); | |
| 259 EXPECT_EQ(ui::VKEY_E, w121delegate->last_key_code()); | |
| 260 } | |
| 261 | |
| 262 // Various destruction assertions. | |
| 263 TEST_F(WindowTest, DestroyTest) { | |
| 264 DestroyTrackingDelegateImpl parent_delegate; | |
| 265 ChildWindowDelegateImpl child_delegate(&parent_delegate); | |
| 266 { | |
| 267 scoped_ptr<Window> parent( | |
| 268 CreateTestWindowWithDelegate(&parent_delegate, 0, gfx::Rect(), NULL)); | |
| 269 Window* child = CreateTestWindowWithDelegate(&child_delegate, 0, | |
| 270 gfx::Rect(), parent.get()); | |
| 271 } | |
| 272 // Both the parent and child should have been destroyed. | |
| 273 EXPECT_EQ(1, parent_delegate.destroying_count()); | |
| 274 EXPECT_EQ(1, parent_delegate.destroyed_count()); | |
| 275 EXPECT_EQ(1, child_delegate.destroying_count()); | |
| 276 EXPECT_EQ(1, child_delegate.destroyed_count()); | |
| 277 } | |
| 278 | |
| 279 } // namespace internal | |
| 280 } // namespace aura | |
| 281 | |
| OLD | NEW |