1 // Copyright 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 "chrome/browser/ui/app_list/app_list_positioner.h" 6 7 #include "base/memory/scoped_ptr.h" 8 #include "testing/gtest/include/gtest/gtest.h" 9 10 namespace { 11 12 const int kScreenWidth = 800; 13 const int kScreenHeight = 600; 14 15 const int kWindowWidth = 100; 16 const int kWindowHeight = 200; 17 18 // Size of the menu bar along the top of the screen. 19 const int kMenuBarSize = 22; 20 // Size of the normal (non-hidden) shelf. 21 const int kShelfSize = 30; 22 23 // The distance the shelf will appear from the edge of the screen. 24 const int kMinDistanceFromEdge = 3; 25 26 // A cursor position that is within the shelf. This must be < kShelfSize. 27 const int kCursorOnShelf = kShelfSize / 2; 28 // A cursor position that should be ignored. 29 const int kCursorIgnore = -300; 30 31 // A position for the center of the window that causes the window to overlap the 32 // edge of the screen. This must be < kWindowWidth / 2 and < kWindowHeight / 2. 33 const int kWindowNearEdge = kWindowWidth / 4; 34 // A position for the center of the window that places the window away from all 35 // edges of the screen. This must be > kWindowWidth / 2, > kWindowHeight / 2, < 36 // kScreenWidth - kWindowWidth / 2 and < kScreenHeight - kWindowHeight / 2. 37 const int kWindowAwayFromEdge = 158; 38 39 } // namespace 40 41 class AppListPositionerUnitTest : public testing::Test { 42 public: 43 void ResetPositioner() { 44 gfx::Size view_size(kWindowWidth, kWindowHeight); 45 positioner_.reset( 46 new AppListPositioner(display_, view_size, kMinDistanceFromEdge)); 47 } 48 49 virtual void SetUp() OVERRIDE { 50 display_.set_bounds(gfx::Rect(0, 0, kScreenWidth, kScreenHeight)); 51 // Assume there is a menu bar at the top of the screen, as on Mac and Unity. 52 // This is for cases where the work area does not fill the entire screen. 53 display_.set_work_area( 54 gfx::Rect(0, kMenuBarSize, kScreenWidth, kScreenHeight - kMenuBarSize)); 55 ResetPositioner(); 56 cursor_ = gfx::Point(); 57 } 58 59 // Sets up the test environment with the shelf along a given edge of the work 60 // area. 61 void PlaceShelf(AppListPositioner::ScreenEdge edge) { 62 ResetPositioner(); 63 switch (edge) { 64 case AppListPositioner::SCREEN_EDGE_UNKNOWN: 65 break; 66 case AppListPositioner::SCREEN_EDGE_LEFT: 67 positioner_->WorkAreaInset(kShelfSize, 0, 0, 0); 68 break; 69 case AppListPositioner::SCREEN_EDGE_RIGHT: 70 positioner_->WorkAreaInset(0, 0, kShelfSize, 0); 71 break; 72 case AppListPositioner::SCREEN_EDGE_TOP: 73 positioner_->WorkAreaInset(0, kShelfSize, 0, 0); 74 break; 75 case AppListPositioner::SCREEN_EDGE_BOTTOM: 76 positioner_->WorkAreaInset(0, 0, 0, kShelfSize); 77 break; 78 } 79 } 80 81 // Set up the test mouse cursor in a given location. 82 void PlaceCursor(int x, int y) { 83 cursor_ = gfx::Point(x, y); 84 } 85 86 gfx::Point DoGetAnchorPointForScreenCorner( 87 AppListPositioner::ScreenCorner corner) const { 88 return positioner_->GetAnchorPointForScreenCorner(corner); 89 } 90 91 gfx::Point DoGetAnchorPointForShelfCorner( 92 AppListPositioner::ScreenEdge shelf_edge) const { 93 return positioner_->GetAnchorPointForShelfCorner(shelf_edge); 94 } 95 96 gfx::Point DoGetAnchorPointForShelfCenter( 97 AppListPositioner::ScreenEdge shelf_edge) const { 98 return positioner_->GetAnchorPointForShelfCenter(shelf_edge); 99 } 100 101 gfx::Point DoGetAnchorPointForShelfCursor( 102 AppListPositioner::ScreenEdge shelf_edge) const { 103 return positioner_->GetAnchorPointForShelfCursor(shelf_edge, cursor_); 104 } 105 106 AppListPositioner::ScreenEdge DoGetShelfEdge( 107 const gfx::Rect& shelf_rect) const { 108 return positioner_->GetShelfEdge(shelf_rect); 109 } 110 111 int DoGetCursorDistanceFromShelf( 112 AppListPositioner::ScreenEdge shelf_edge) const { 113 return positioner_->GetCursorDistanceFromShelf(shelf_edge, cursor_); 114 } 115 116 private: 117 gfx::Display display_; 118 scoped_ptr<AppListPositioner> positioner_; 119 gfx::Point cursor_; 120 }; 121 122 TEST_F(AppListPositionerUnitTest, ScreenCorner) { 123 // Position the app list in a corner of the screen. 124 // Top-left corner. 125 EXPECT_EQ(gfx::Point(kWindowWidth / 2 + kMinDistanceFromEdge, 126 kMenuBarSize + kWindowHeight / 2 + kMinDistanceFromEdge), 127 DoGetAnchorPointForScreenCorner( 128 AppListPositioner::SCREEN_CORNER_TOP_LEFT)); 129 130 // Top-right corner. 131 EXPECT_EQ(gfx::Point(kScreenWidth - kWindowWidth / 2 - kMinDistanceFromEdge, 132 kMenuBarSize + kWindowHeight / 2 + kMinDistanceFromEdge), 133 DoGetAnchorPointForScreenCorner( 134 AppListPositioner::SCREEN_CORNER_TOP_RIGHT)); 135 136 // Bottom-left corner. 137 EXPECT_EQ( 138 gfx::Point(kWindowWidth / 2 + kMinDistanceFromEdge, 139 kScreenHeight - kWindowHeight / 2 - kMinDistanceFromEdge), 140 DoGetAnchorPointForScreenCorner( 141 AppListPositioner::SCREEN_CORNER_BOTTOM_LEFT)); 142 143 // Bottom-right corner. 144 EXPECT_EQ( 145 gfx::Point(kScreenWidth - kWindowWidth / 2 - kMinDistanceFromEdge, 146 kScreenHeight - kWindowHeight / 2 - kMinDistanceFromEdge), 147 DoGetAnchorPointForScreenCorner( 148 AppListPositioner::SCREEN_CORNER_BOTTOM_RIGHT)); 149 } 150 151 TEST_F(AppListPositionerUnitTest, ShelfCorner) { 152 // Position the app list on the shelf, aligned with the top or left corner. 153 // Shelf on left. Expect app list in top-left corner. 154 PlaceShelf(AppListPositioner::SCREEN_EDGE_LEFT); 155 EXPECT_EQ( 156 gfx::Point(kShelfSize + kWindowWidth / 2 + kMinDistanceFromEdge, 157 kMenuBarSize + kWindowHeight / 2 + kMinDistanceFromEdge), 158 DoGetAnchorPointForShelfCorner(AppListPositioner::SCREEN_EDGE_LEFT)); 159 160 // Shelf on right. Expect app list in top-right corner. 161 PlaceShelf(AppListPositioner::SCREEN_EDGE_RIGHT); 162 EXPECT_EQ( 163 gfx::Point( 164 kScreenWidth - kShelfSize - kWindowWidth / 2 - kMinDistanceFromEdge, 165 kMenuBarSize + kWindowHeight / 2 + kMinDistanceFromEdge), 166 DoGetAnchorPointForShelfCorner(AppListPositioner::SCREEN_EDGE_RIGHT)); 167 168 // Shelf on top. Expect app list in top-left corner. 169 PlaceShelf(AppListPositioner::SCREEN_EDGE_TOP); 170 EXPECT_EQ(gfx::Point(kWindowWidth / 2 + kMinDistanceFromEdge, 171 kMenuBarSize + kShelfSize + kWindowHeight / 2 + 172 kMinDistanceFromEdge), 173 DoGetAnchorPointForShelfCorner(AppListPositioner::SCREEN_EDGE_TOP)); 174 175 // Shelf on bottom. Expect app list in bottom-left corner. 176 PlaceShelf(AppListPositioner::SCREEN_EDGE_BOTTOM); 177 EXPECT_EQ( 178 gfx::Point(kWindowWidth / 2 + kMinDistanceFromEdge, 179 kScreenHeight - kShelfSize - kWindowHeight / 2 - 180 kMinDistanceFromEdge), 181 DoGetAnchorPointForShelfCorner(AppListPositioner::SCREEN_EDGE_BOTTOM)); 182 } 183 184 TEST_F(AppListPositionerUnitTest, ShelfCenter) { 185 // Position the app list on the shelf, aligned with the shelf center. 186 PlaceShelf(AppListPositioner::SCREEN_EDGE_LEFT); 187 // Shelf on left. Expect app list to be center-left. 188 EXPECT_EQ( 189 gfx::Point(kShelfSize + kWindowWidth / 2 + kMinDistanceFromEdge, 190 (kMenuBarSize + kScreenHeight) / 2), 191 DoGetAnchorPointForShelfCenter(AppListPositioner::SCREEN_EDGE_LEFT)); 192 193 // Shelf on right. Expect app list to be center-right. 194 PlaceShelf(AppListPositioner::SCREEN_EDGE_RIGHT); 195 EXPECT_EQ( 196 gfx::Point( 197 kScreenWidth - kShelfSize - kWindowWidth / 2 - kMinDistanceFromEdge, 198 (kMenuBarSize + kScreenHeight) / 2), 199 DoGetAnchorPointForShelfCenter(AppListPositioner::SCREEN_EDGE_RIGHT)); 200 201 // Shelf on top. Expect app list to be top-center. 202 PlaceShelf(AppListPositioner::SCREEN_EDGE_TOP); 203 EXPECT_EQ(gfx::Point(kScreenWidth / 2, 204 kMenuBarSize + kShelfSize + kWindowHeight / 2 + 205 kMinDistanceFromEdge), 206 DoGetAnchorPointForShelfCenter(AppListPositioner::SCREEN_EDGE_TOP)); 207 208 // Shelf on bottom. Expect app list to be bottom-center. 209 PlaceShelf(AppListPositioner::SCREEN_EDGE_BOTTOM); 210 EXPECT_EQ( 211 gfx::Point(kScreenWidth / 2, 212 kScreenHeight - kShelfSize - kWindowHeight / 2 - 213 kMinDistanceFromEdge), 214 DoGetAnchorPointForShelfCenter(AppListPositioner::SCREEN_EDGE_BOTTOM)); 215 } 216 217 TEST_F(AppListPositionerUnitTest, ShelfCursor) { 218 // Position the app list on the shelf, aligned with the mouse cursor. 219 220 // Shelf on left. Expect app list in top-left corner. 221 PlaceShelf(AppListPositioner::SCREEN_EDGE_LEFT); 222 PlaceCursor(kCursorIgnore, kWindowAwayFromEdge); 223 EXPECT_EQ( 224 gfx::Point(kShelfSize + kWindowWidth / 2 + kMinDistanceFromEdge, 225 kWindowAwayFromEdge), 226 DoGetAnchorPointForShelfCursor(AppListPositioner::SCREEN_EDGE_LEFT)); 227 228 // Shelf on right. Expect app list in top-right corner. 229 PlaceShelf(AppListPositioner::SCREEN_EDGE_RIGHT); 230 PlaceCursor(kCursorIgnore, kWindowAwayFromEdge); 231 EXPECT_EQ( 232 gfx::Point( 233 kScreenWidth - kShelfSize - kWindowWidth / 2 - kMinDistanceFromEdge, 234 kWindowAwayFromEdge), 235 DoGetAnchorPointForShelfCursor(AppListPositioner::SCREEN_EDGE_RIGHT)); 236 237 // Shelf on top. Expect app list in top-left corner. 238 PlaceShelf(AppListPositioner::SCREEN_EDGE_TOP); 239 PlaceCursor(kWindowAwayFromEdge, kCursorIgnore); 240 EXPECT_EQ(gfx::Point(kWindowAwayFromEdge, 241 kMenuBarSize + kShelfSize + kWindowHeight / 2 + 242 kMinDistanceFromEdge), 243 DoGetAnchorPointForShelfCursor(AppListPositioner::SCREEN_EDGE_TOP)); 244 245 // Shelf on bottom. Expect app list in bottom-left corner. 246 PlaceShelf(AppListPositioner::SCREEN_EDGE_BOTTOM); 247 PlaceCursor(kWindowAwayFromEdge, kCursorIgnore); 248 EXPECT_EQ( 249 gfx::Point(kWindowAwayFromEdge, 250 kScreenHeight - kShelfSize - kWindowHeight / 2 - 251 kMinDistanceFromEdge), 252 DoGetAnchorPointForShelfCursor(AppListPositioner::SCREEN_EDGE_BOTTOM)); 253 254 // Shelf on bottom. Mouse near left edge. App list must not go off screen. 255 PlaceShelf(AppListPositioner::SCREEN_EDGE_BOTTOM); 256 PlaceCursor(kWindowNearEdge, kCursorIgnore); 257 EXPECT_EQ( 258 gfx::Point(kWindowWidth / 2 + kMinDistanceFromEdge, 259 kScreenHeight - kShelfSize - kWindowHeight / 2 - 260 kMinDistanceFromEdge), 261 DoGetAnchorPointForShelfCursor(AppListPositioner::SCREEN_EDGE_BOTTOM)); 262 263 // Shelf on bottom. Mouse near right edge. App list must not go off screen. 264 PlaceShelf(AppListPositioner::SCREEN_EDGE_BOTTOM); 265 PlaceCursor(kScreenWidth - kWindowNearEdge, kCursorIgnore); 266 EXPECT_EQ( 267 gfx::Point(kScreenWidth - kWindowWidth / 2 - kMinDistanceFromEdge, 268 kScreenHeight - kShelfSize - kWindowHeight / 2 - 269 kMinDistanceFromEdge), 270 DoGetAnchorPointForShelfCursor(AppListPositioner::SCREEN_EDGE_BOTTOM)); 271 } 272 273 TEST_F(AppListPositionerUnitTest, GetShelfEdge) { 274 gfx::Rect shelf_rect; 275 // Shelf on left. 276 shelf_rect = 277 gfx::Rect(0, kMenuBarSize, kShelfSize, kScreenHeight - kMenuBarSize); 278 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_LEFT, DoGetShelfEdge(shelf_rect)); 279 280 // Shelf on right. 281 shelf_rect = gfx::Rect(kScreenWidth - kShelfSize, 282 kMenuBarSize, 283 kShelfSize, 284 kScreenHeight - kMenuBarSize); 285 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_RIGHT, DoGetShelfEdge(shelf_rect)); 286 287 // Shelf on top. 288 shelf_rect = gfx::Rect(0, 0, kScreenWidth, kShelfSize); 289 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_TOP, DoGetShelfEdge(shelf_rect)); 290 291 // Shelf on bottom. 292 shelf_rect = 293 gfx::Rect(0, kScreenHeight - kShelfSize, kScreenWidth, kShelfSize); 294 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_BOTTOM, DoGetShelfEdge(shelf_rect)); 295 296 // A couple of inconclusive cases, which should return unknown. 297 shelf_rect = gfx::Rect(); 298 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_UNKNOWN, DoGetShelfEdge(shelf_rect)); 299 shelf_rect = gfx::Rect(-10, 0, kScreenWidth, kShelfSize); 300 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_UNKNOWN, DoGetShelfEdge(shelf_rect)); 301 shelf_rect = gfx::Rect(10, 0, kScreenWidth - 20, kShelfSize); 302 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_UNKNOWN, DoGetShelfEdge(shelf_rect)); 303 shelf_rect = gfx::Rect(0, kShelfSize, kScreenWidth, 60); 304 EXPECT_EQ(AppListPositioner::SCREEN_EDGE_UNKNOWN, DoGetShelfEdge(shelf_rect)); 305 } 306 307 TEST_F(AppListPositionerUnitTest, GetCursorDistanceFromShelf) { 308 // Shelf on left. 309 PlaceShelf(AppListPositioner::SCREEN_EDGE_LEFT); 310 PlaceCursor(kWindowAwayFromEdge, kCursorIgnore); 311 EXPECT_EQ(kWindowAwayFromEdge - kShelfSize, 312 DoGetCursorDistanceFromShelf(AppListPositioner::SCREEN_EDGE_LEFT)); 313 314 // Shelf on right. 315 PlaceShelf(AppListPositioner::SCREEN_EDGE_RIGHT); 316 PlaceCursor(kScreenWidth - kWindowAwayFromEdge, kCursorIgnore); 317 EXPECT_EQ(kWindowAwayFromEdge - kShelfSize, 318 DoGetCursorDistanceFromShelf(AppListPositioner::SCREEN_EDGE_RIGHT)); 319 320 // Shelf on top. 321 PlaceShelf(AppListPositioner::SCREEN_EDGE_TOP); 322 PlaceCursor(kCursorIgnore, kMenuBarSize + kWindowAwayFromEdge); 323 EXPECT_EQ(kWindowAwayFromEdge - kShelfSize, 324 DoGetCursorDistanceFromShelf(AppListPositioner::SCREEN_EDGE_TOP)); 325 326 // Shelf on bottom. 327 PlaceShelf(AppListPositioner::SCREEN_EDGE_BOTTOM); 328 PlaceCursor(kCursorIgnore, kScreenHeight - kWindowAwayFromEdge); 329 EXPECT_EQ( 330 kWindowAwayFromEdge - kShelfSize, 331 DoGetCursorDistanceFromShelf(AppListPositioner::SCREEN_EDGE_BOTTOM)); 332 333 // Shelf on bottom. Cursor inside shelf; expect 0. 334 PlaceShelf(AppListPositioner::SCREEN_EDGE_BOTTOM); 335 PlaceCursor(kCursorIgnore, kScreenHeight - kCursorOnShelf); 336 EXPECT_EQ( 337 0, DoGetCursorDistanceFromShelf(AppListPositioner::SCREEN_EDGE_BOTTOM)); 338 } 339