Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / app_list / app_list_positioner.cc
blob968b53ac105f58bd8661cecd518686c5a3e8a783
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.
5 #include "chrome/browser/ui/app_list/app_list_positioner.h"
7 #include <algorithm>
9 #include "base/logging.h"
10 #include "ui/gfx/point.h"
11 #include "ui/gfx/rect.h"
13 AppListPositioner::AppListPositioner(const gfx::Display& display,
14 const gfx::Size& window_size,
15 int min_distance_from_edge)
16 : display_(display),
17 window_size_(window_size),
18 min_distance_from_edge_(min_distance_from_edge) {}
20 void AppListPositioner::WorkAreaSubtract(const gfx::Rect& rect) {
21 gfx::Rect work_area = display_.work_area();
22 work_area.Subtract(rect);
23 display_.set_work_area(work_area);
26 void AppListPositioner::WorkAreaInset(int left,
27 int top,
28 int right,
29 int bottom) {
30 gfx::Rect work_area = display_.work_area();
31 work_area.Inset(left, top, right, bottom);
32 display_.set_work_area(work_area);
35 gfx::Point AppListPositioner::GetAnchorPointForScreenCorner(
36 ScreenCorner corner) const {
37 const gfx::Rect& screen_rect = display_.bounds();
38 gfx::Point anchor;
39 switch (corner) {
40 case SCREEN_CORNER_TOP_LEFT:
41 anchor = screen_rect.origin();
42 break;
43 case SCREEN_CORNER_TOP_RIGHT:
44 anchor = screen_rect.top_right();
45 break;
46 case SCREEN_CORNER_BOTTOM_LEFT:
47 anchor = screen_rect.bottom_left();
48 break;
49 case SCREEN_CORNER_BOTTOM_RIGHT:
50 anchor = screen_rect.bottom_right();
51 break;
52 default:
53 NOTREACHED();
54 anchor = gfx::Point();
56 return ClampAnchorPoint(anchor);
59 gfx::Point AppListPositioner::GetAnchorPointForShelfCorner(
60 ScreenEdge shelf_edge) const {
61 const gfx::Rect& screen_rect = display_.bounds();
62 const gfx::Rect& work_area = display_.work_area();
63 gfx::Point anchor;
64 switch (shelf_edge) {
65 case SCREEN_EDGE_LEFT:
66 anchor = gfx::Point(work_area.x(), screen_rect.y());
67 break;
68 case SCREEN_EDGE_RIGHT:
69 anchor = gfx::Point(work_area.right(), screen_rect.y());
70 break;
71 case SCREEN_EDGE_TOP:
72 anchor = gfx::Point(screen_rect.x(), work_area.y());
73 break;
74 case SCREEN_EDGE_BOTTOM:
75 anchor = gfx::Point(screen_rect.x(), work_area.bottom());
76 break;
77 default:
78 NOTREACHED();
79 anchor = gfx::Point();
81 return ClampAnchorPoint(anchor);
84 gfx::Point AppListPositioner::GetAnchorPointForShelfCenter(
85 ScreenEdge shelf_edge) const {
86 const gfx::Rect& work_area = display_.work_area();
87 gfx::Point anchor;
88 switch (shelf_edge) {
89 case SCREEN_EDGE_LEFT:
90 anchor =
91 gfx::Point(work_area.x(), work_area.y() + work_area.height() / 2);
92 break;
93 case SCREEN_EDGE_RIGHT:
94 anchor =
95 gfx::Point(work_area.right(), work_area.y() + work_area.height() / 2);
96 break;
97 case SCREEN_EDGE_TOP:
98 anchor = gfx::Point(work_area.x() + work_area.width() / 2, work_area.y());
99 break;
100 case SCREEN_EDGE_BOTTOM:
101 anchor =
102 gfx::Point(work_area.x() + work_area.width() / 2, work_area.bottom());
103 break;
104 default:
105 NOTREACHED();
106 anchor = gfx::Point();
108 return ClampAnchorPoint(anchor);
111 gfx::Point AppListPositioner::GetAnchorPointForShelfCursor(
112 ScreenEdge shelf_edge,
113 const gfx::Point& cursor) const {
114 const gfx::Rect& work_area = display_.work_area();
115 gfx::Point anchor;
116 switch (shelf_edge) {
117 case SCREEN_EDGE_LEFT:
118 anchor = gfx::Point(work_area.x(), cursor.y());
119 break;
120 case SCREEN_EDGE_RIGHT:
121 anchor = gfx::Point(work_area.right(), cursor.y());
122 break;
123 case SCREEN_EDGE_TOP:
124 anchor = gfx::Point(cursor.x(), work_area.y());
125 break;
126 case SCREEN_EDGE_BOTTOM:
127 anchor = gfx::Point(cursor.x(), work_area.bottom());
128 break;
129 default:
130 NOTREACHED();
131 anchor = gfx::Point();
133 return ClampAnchorPoint(anchor);
136 AppListPositioner::ScreenEdge AppListPositioner::GetShelfEdge(
137 const gfx::Rect& shelf_rect) const {
138 const gfx::Rect& screen_rect = display_.bounds();
139 const gfx::Rect& work_area = display_.work_area();
141 // If we can't find the shelf, return SCREEN_EDGE_UNKNOWN. If the display
142 // size is the same as the work area, and does not contain the shelf, either
143 // the shelf is hidden or on another monitor.
144 if (work_area == screen_rect && !work_area.Contains(shelf_rect))
145 return SCREEN_EDGE_UNKNOWN;
147 // Note: On Windows 8 the work area won't include split windows on the left or
148 // right, and neither will |shelf_rect|.
149 if (shelf_rect.x() == work_area.x() &&
150 shelf_rect.width() == work_area.width()) {
151 // Shelf is horizontal.
152 if (shelf_rect.bottom() == screen_rect.bottom())
153 return SCREEN_EDGE_BOTTOM;
154 else if (shelf_rect.y() == screen_rect.y())
155 return SCREEN_EDGE_TOP;
156 } else if (shelf_rect.y() == work_area.y() &&
157 shelf_rect.height() == work_area.height()) {
158 // Shelf is vertical.
159 if (shelf_rect.x() == screen_rect.x())
160 return SCREEN_EDGE_LEFT;
161 else if (shelf_rect.right() == screen_rect.right())
162 return SCREEN_EDGE_RIGHT;
165 return SCREEN_EDGE_UNKNOWN;
168 int AppListPositioner::GetCursorDistanceFromShelf(
169 ScreenEdge shelf_edge,
170 const gfx::Point& cursor) const {
171 const gfx::Rect& work_area = display_.work_area();
172 switch (shelf_edge) {
173 case SCREEN_EDGE_UNKNOWN:
174 return 0;
175 case SCREEN_EDGE_LEFT:
176 return std::max(0, cursor.x() - work_area.x());
177 case SCREEN_EDGE_RIGHT:
178 return std::max(0, work_area.right() - cursor.x());
179 case SCREEN_EDGE_TOP:
180 return std::max(0, cursor.y() - work_area.y());
181 case SCREEN_EDGE_BOTTOM:
182 return std::max(0, work_area.bottom() - cursor.y());
183 default:
184 NOTREACHED();
185 return 0;
189 gfx::Point AppListPositioner::ClampAnchorPoint(gfx::Point anchor) const {
190 gfx::Rect bounds_rect(display_.work_area());
192 // Anchor the center of the window in a region that prevents the window
193 // showing outside of the work area.
194 bounds_rect.Inset(window_size_.width() / 2 + min_distance_from_edge_,
195 window_size_.height() / 2 + min_distance_from_edge_);
197 anchor.SetToMax(bounds_rect.origin());
198 anchor.SetToMin(bounds_rect.bottom_right());
199 return anchor;