Home | History | Annotate | Download | only in app_list
      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