panel_window_resizer_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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 "ash/wm/panels/panel_window_resizer.h" 6 7#include "ash/launcher/launcher.h" 8#include "ash/launcher/launcher_model.h" 9#include "ash/root_window_controller.h" 10#include "ash/shelf/shelf_types.h" 11#include "ash/shelf/shelf_widget.h" 12#include "ash/shell.h" 13#include "ash/shell_window_ids.h" 14#include "ash/test/ash_test_base.h" 15#include "ash/test/cursor_manager_test_api.h" 16#include "ash/test/shell_test_api.h" 17#include "ash/test/test_launcher_delegate.h" 18#include "ash/wm/panels/panel_layout_manager.h" 19#include "ash/wm/window_properties.h" 20#include "ui/aura/client/aura_constants.h" 21#include "ui/aura/root_window.h" 22#include "ui/base/hit_test.h" 23#include "ui/base/ui_base_types.h" 24#include "ui/views/widget/widget.h" 25 26namespace ash { 27namespace internal { 28 29class PanelWindowResizerTest : public test::AshTestBase { 30 public: 31 PanelWindowResizerTest() {} 32 virtual ~PanelWindowResizerTest() {} 33 34 virtual void SetUp() OVERRIDE { 35 AshTestBase::SetUp(); 36 test::ShellTestApi test_api(Shell::GetInstance()); 37 model_ = test_api.launcher_model(); 38 39 panel_layout_manager_ = static_cast<internal::PanelLayoutManager*>( 40 GetPanelContainer()->layout_manager()); 41 launcher_bounds_ = panel_layout_manager_->launcher()->shelf_widget()-> 42 GetWindowBoundsInScreen(); 43 } 44 45 virtual void TearDown() OVERRIDE { 46 AshTestBase::TearDown(); 47 } 48 49 protected: 50 gfx::Point CalculateDragPoint(const PanelWindowResizer& resizer, 51 int delta_x, 52 int delta_y) const { 53 gfx::Point location = resizer.GetInitialLocationInParentForTest(); 54 location.set_x(location.x() + delta_x); 55 location.set_y(location.y() + delta_y); 56 return location; 57 } 58 59 aura::Window* CreatePanelWindow(const gfx::Rect& bounds) { 60 aura::Window* window = CreateTestWindowInShellWithDelegateAndType( 61 NULL, 62 aura::client::WINDOW_TYPE_PANEL, 63 0, 64 bounds); 65 test::TestLauncherDelegate* launcher_delegate = 66 test::TestLauncherDelegate::instance(); 67 launcher_delegate->AddLauncherItem(window); 68 PanelLayoutManager* manager = 69 static_cast<PanelLayoutManager*>(GetPanelContainer()->layout_manager()); 70 manager->Relayout(); 71 return window; 72 } 73 74 aura::Window* GetPanelContainer() { 75 return Shell::GetContainer( 76 Shell::GetPrimaryRootWindow(), 77 internal::kShellWindowId_PanelContainer); 78 } 79 80 static PanelWindowResizer* CreatePanelWindowResizer( 81 aura::Window* window, 82 const gfx::Point& point_in_parent, 83 int window_component) { 84 return static_cast<PanelWindowResizer*>(CreateWindowResizer( 85 window, point_in_parent, window_component).release()); 86 } 87 88 void DragStart(aura::Window* window) { 89 resizer_.reset(CreatePanelWindowResizer(window, gfx::Point(), HTCAPTION)); 90 ASSERT_TRUE(resizer_.get()); 91 } 92 93 void DragMove(int dx, int dy) { 94 resizer_->Drag(CalculateDragPoint(*resizer_, dx, dy), 0); 95 } 96 97 void DragEnd() { 98 resizer_->CompleteDrag(0); 99 resizer_.reset(); 100 } 101 102 // Test dragging the panel slightly, then detaching, and then reattaching 103 // dragging out by the vector (dx, dy). 104 void DetachReattachTest(int dx, int dy) { 105 scoped_ptr<aura::Window> window( 106 CreatePanelWindow(gfx::Rect(0, 0, 201, 201))); 107 EXPECT_TRUE(window->GetProperty(kPanelAttachedKey)); 108 EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id()); 109 DragStart(window.get()); 110 gfx::Rect initial_bounds = window->bounds(); 111 112 // Drag the panel slightly. The window should still be snapped to the 113 // launcher. 114 DragMove(dx * 5, dy * 5); 115 EXPECT_EQ(initial_bounds.x(), window->bounds().x()); 116 EXPECT_EQ(initial_bounds.y(), window->bounds().y()); 117 118 // Drag further out and the window should now move to the cursor. 119 DragMove(dx * 100, dy * 100); 120 EXPECT_EQ(initial_bounds.x() + dx * 100, window->bounds().x()); 121 EXPECT_EQ(initial_bounds.y() + dy * 100, window->bounds().y()); 122 123 // The panel should be detached when the drag completes. 124 DragEnd(); 125 EXPECT_FALSE(window->GetProperty(kPanelAttachedKey)); 126 EXPECT_EQ(internal::kShellWindowId_WorkspaceContainer, 127 window->parent()->id()); 128 129 DragStart(window.get()); 130 // Drag the panel down. 131 DragMove(dx * -95, dy * -95); 132 // Release the mouse and the panel should be reattached. 133 DragEnd(); 134 135 // The panel should be reattached and have snapped to the launcher. 136 EXPECT_TRUE(window->GetProperty(kPanelAttachedKey)); 137 EXPECT_EQ(initial_bounds.x(), window->bounds().x()); 138 EXPECT_EQ(initial_bounds.y(), window->bounds().y()); 139 EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id()); 140 } 141 142 void TestWindowOrder(const std::vector<aura::Window*>& window_order) { 143 Launcher* launcher = Launcher::ForPrimaryDisplay(); 144 int panel_index = model_->FirstPanelIndex(); 145 EXPECT_EQ((int)(panel_index + window_order.size()), model_->item_count()); 146 for (std::vector<aura::Window*>::const_iterator iter = 147 window_order.begin(); iter != window_order.end(); 148 ++iter, ++panel_index) { 149 LauncherID id = launcher->delegate()->GetIDByWindow(*iter); 150 EXPECT_EQ(id, model_->items()[panel_index].id); 151 } 152 } 153 154 // Test dragging panel window along the shelf and verify that panel icons 155 // are reordered appropriately. 156 void DragAlongShelfReorder(int dx, int dy) { 157 gfx::Rect bounds(0, 0, 201, 201); 158 scoped_ptr<aura::Window> w1(CreatePanelWindow(bounds)); 159 scoped_ptr<aura::Window> w2(CreatePanelWindow(bounds)); 160 std::vector<aura::Window*> window_order_original; 161 std::vector<aura::Window*> window_order_swapped; 162 window_order_original.push_back(w1.get()); 163 window_order_original.push_back(w2.get()); 164 window_order_swapped.push_back(w2.get()); 165 window_order_swapped.push_back(w1.get()); 166 TestWindowOrder(window_order_original); 167 168 // Drag window #2 to the beginning of the shelf. 169 DragStart(w2.get()); 170 DragMove(400 * dx, 400 * dy); 171 DragEnd(); 172 173 // Expect swapped window order. 174 TestWindowOrder(window_order_swapped); 175 176 // Drag window #2 back to the end. 177 DragStart(w2.get()); 178 DragMove(-400 * dx, -400 * dy); 179 DragEnd(); 180 181 // Expect original order. 182 TestWindowOrder(window_order_original); 183 } 184 185 private: 186 scoped_ptr<PanelWindowResizer> resizer_; 187 aura::Window* panel_container_; 188 internal::PanelLayoutManager* panel_layout_manager_; 189 gfx::Rect launcher_bounds_; 190 LauncherModel* model_; 191 192 DISALLOW_COPY_AND_ASSIGN(PanelWindowResizerTest); 193}; 194 195// Verifies a window can be dragged from the panel and detached and then 196// reattached. 197TEST_F(PanelWindowResizerTest, PanelDetachReattachBottom) { 198 DetachReattachTest(0, -1); 199} 200 201TEST_F(PanelWindowResizerTest, PanelDetachReattachLeft) { 202 ash::Shell* shell = ash::Shell::GetInstance(); 203 shell->SetShelfAlignment(SHELF_ALIGNMENT_LEFT, shell->GetPrimaryRootWindow()); 204 DetachReattachTest(1, 0); 205} 206 207#if defined(OS_WIN) 208// TODO(flackr): Positioning of the panel seems to be off on Windows Aura when 209// attached to the right (http://crbug.com/180892). 210#define MAYBE_PanelDetachReattachRight DISABLED_PanelDetachReattachRight 211#else 212#define MAYBE_PanelDetachReattachRight PanelDetachReattachRight 213#endif 214 215TEST_F(PanelWindowResizerTest, MAYBE_PanelDetachReattachRight) { 216 ash::Shell* shell = ash::Shell::GetInstance(); 217 shell->SetShelfAlignment(SHELF_ALIGNMENT_RIGHT, 218 shell->GetPrimaryRootWindow()); 219 DetachReattachTest(-1, 0); 220} 221 222TEST_F(PanelWindowResizerTest, PanelDetachReattachTop) { 223 ash::Shell* shell = ash::Shell::GetInstance(); 224 shell->SetShelfAlignment(SHELF_ALIGNMENT_TOP, shell->GetPrimaryRootWindow()); 225 DetachReattachTest(0, 1); 226} 227 228TEST_F(PanelWindowResizerTest, DragMovesToPanelLayer) { 229 scoped_ptr<aura::Window> window(CreatePanelWindow(gfx::Rect(0, 0, 201, 201))); 230 DragStart(window.get()); 231 DragMove(0, -100); 232 DragEnd(); 233 EXPECT_EQ(internal::kShellWindowId_WorkspaceContainer, 234 window->parent()->id()); 235 236 // While moving the panel window should be moved to the panel container. 237 DragStart(window.get()); 238 DragMove(20, 0); 239 EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id()); 240 DragEnd(); 241 242 // When dropped it should return to the default container. 243 EXPECT_EQ(internal::kShellWindowId_WorkspaceContainer, 244 window->parent()->id()); 245} 246 247TEST_F(PanelWindowResizerTest, DragReordersPanelsHorizontal) { 248 DragAlongShelfReorder(-1, 0); 249} 250 251TEST_F(PanelWindowResizerTest, DragReordersPanelsVertical) { 252 ash::Shell* shell = ash::Shell::GetInstance(); 253 shell->SetShelfAlignment(SHELF_ALIGNMENT_LEFT, shell->GetPrimaryRootWindow()); 254 DragAlongShelfReorder(0, -1); 255} 256 257} // namespace internal 258} // namespace ash 259