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#ifndef CHROME_BROWSER_UI_APP_LIST_APP_LIST_POSITIONER_H_
6#define CHROME_BROWSER_UI_APP_LIST_APP_LIST_POSITIONER_H_
7
8#include "ui/gfx/display.h"
9#include "ui/gfx/size.h"
10
11namespace gfx {
12class Point;
13class Rect;
14}
15
16// Helps anchor the App List, onto the shelf (taskbar, dock or similar) or to
17// the corner of a display. This class does not impose any particular policy for
18// when and how to anchor the window. The platform-specific code that uses this
19// class is free to decide, for example, when the window should be anchored to
20// the cursor versus the corner of the shelf. This class just performs the
21// calculations necessary to position the App List correctly.
22class AppListPositioner {
23 public:
24  // Represents one of the four edges of the screen.
25  enum ScreenEdge {
26    SCREEN_EDGE_UNKNOWN,
27    SCREEN_EDGE_LEFT,
28    SCREEN_EDGE_RIGHT,
29    SCREEN_EDGE_TOP,
30    SCREEN_EDGE_BOTTOM
31  };
32
33  // Represents one of the four corners of the screen.
34  enum ScreenCorner {
35    SCREEN_CORNER_TOP_LEFT,
36    SCREEN_CORNER_TOP_RIGHT,
37    SCREEN_CORNER_BOTTOM_LEFT,
38    SCREEN_CORNER_BOTTOM_RIGHT
39  };
40
41  // The |display| pointer is borrowed, and must outlive this object's lifetime.
42  // |window_size| is the size of the App List.
43  // |min_distance_from_edge| is the minimum distance, in pixels, to position
44  // the app list from the shelf or edge of screen.
45  AppListPositioner(const gfx::Display& display,
46                    const gfx::Size& window_size,
47                    int min_distance_from_edge);
48
49  // Subtracts a rectangle from the display's work area. This can be used to
50  // ensure that the app list does not overlap the shelf, even in situations
51  // where the shelf is considered part of the work area.
52  void WorkAreaSubtract(const gfx::Rect& rect);
53
54  // Shrinks the display's work area by the given amount on each side.
55  void WorkAreaInset(int left, int top, int right, int bottom);
56
57  // Finds the position for a window to anchor it to a corner of the screen.
58  // |corner| specifies which corner to anchor the window to. Returns the
59  // intended coordinates for the center of the window. This should only be used
60  // when there is no shelf on the display, because if there is, the returned
61  // anchor point will potentially position the window under it.
62  gfx::Point GetAnchorPointForScreenCorner(ScreenCorner corner) const;
63
64  // Finds the position for a window to anchor it to the center of the screen.
65  // Returns the intended coordinates for the center of the window.
66  gfx::Point GetAnchorPointForScreenCenter() const;
67
68  // Finds the position for a window to anchor it to the corner of the shelf.
69  // The window will be aligned to the left of the work area for horizontal
70  // shelves, or to the top for vertical shelves. |shelf_edge| specifies the
71  // location of the shelf. |shelf_edge| must not be SCREEN_EDGE_UNKNOWN.
72  // Returns the intended coordinates for the center of the window.
73  gfx::Point GetAnchorPointForShelfCorner(ScreenEdge shelf_edge) const;
74
75  // Finds the position for a window to anchor it to the center of the shelf.
76  // |shelf_edge| specifies the location of the shelf. It must not be
77  // SCREEN_EDGE_UNKNOWN. Returns the intended coordinates for the center of the
78  // window.
79  gfx::Point GetAnchorPointForShelfCenter(ScreenEdge shelf_edge) const;
80
81  // Finds the position for a window to anchor it to the shelf at a point
82  // closest to the user's mouse cursor. |shelf_edge| specifies the location of
83  // the shelf; |cursor| specifies the location of the user's mouse cursor.
84  // |shelf_edge| must not be SCREEN_EDGE_UNKNOWN. Returns the intended
85  // coordinates for the center of the window.
86  gfx::Point GetAnchorPointForShelfCursor(ScreenEdge shelf_edge,
87                                          const gfx::Point& cursor) const;
88
89  // Determines which edge of the screen the shelf is attached to. Returns
90  // SCREEN_EDGE_UNKNOWN if the shelf is unavailable, hidden, or not on the
91  // current screen.
92  ScreenEdge GetShelfEdge(const gfx::Rect& shelf_rect) const;
93
94  // Gets the lateral distance of the mouse cursor from the edge of the shelf.
95  // For horizontal shelves, this is the vertical distance; for vertical
96  // shelves, this is the horizontal distance. If the cursor is inside the
97  // shelf, returns 0.
98  int GetCursorDistanceFromShelf(ScreenEdge shelf_edge,
99                                 const gfx::Point& cursor) const;
100
101 private:
102  // Ensures that an anchor point will result in a window that is fully within
103  // the work area. Returns the updated anchor point.
104  gfx::Point ClampAnchorPoint(gfx::Point anchor) const;
105
106  gfx::Display display_;
107
108  // Size of the App List.
109  gfx::Size window_size_;
110
111  // The minimum distance, in pixels, to position the app list from the shelf
112  // or edge of screen.
113  int min_distance_from_edge_;
114};
115
116#endif  // CHROME_BROWSER_UI_APP_LIST_APP_LIST_POSITIONER_H_
117