| OLD | NEW |
| (Empty) |
| 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 <algorithm> | |
| 8 | |
| 9 #include "base/logging.h" | |
| 10 #include "ui/gfx/geometry/point.h" | |
| 11 #include "ui/gfx/geometry/rect.h" | |
| 12 | |
| 13 AppListPositioner::AppListPositioner(const display::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) {} | |
| 19 | |
| 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); | |
| 24 } | |
| 25 | |
| 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); | |
| 33 } | |
| 34 | |
| 35 gfx::Point AppListPositioner::GetAnchorPointForScreenCenter() const { | |
| 36 return display_.bounds().CenterPoint(); | |
| 37 } | |
| 38 | |
| 39 gfx::Point AppListPositioner::GetAnchorPointForScreenCorner( | |
| 40 ScreenCorner corner) const { | |
| 41 const gfx::Rect& screen_rect = display_.bounds(); | |
| 42 gfx::Point anchor; | |
| 43 switch (corner) { | |
| 44 case SCREEN_CORNER_TOP_LEFT: | |
| 45 anchor = screen_rect.origin(); | |
| 46 break; | |
| 47 case SCREEN_CORNER_TOP_RIGHT: | |
| 48 anchor = screen_rect.top_right(); | |
| 49 break; | |
| 50 case SCREEN_CORNER_BOTTOM_LEFT: | |
| 51 anchor = screen_rect.bottom_left(); | |
| 52 break; | |
| 53 case SCREEN_CORNER_BOTTOM_RIGHT: | |
| 54 anchor = screen_rect.bottom_right(); | |
| 55 break; | |
| 56 default: | |
| 57 NOTREACHED(); | |
| 58 anchor = gfx::Point(); | |
| 59 } | |
| 60 return ClampAnchorPoint(anchor); | |
| 61 } | |
| 62 | |
| 63 gfx::Point AppListPositioner::GetAnchorPointForShelfCorner( | |
| 64 ScreenEdge shelf_edge) const { | |
| 65 const gfx::Rect& screen_rect = display_.bounds(); | |
| 66 const gfx::Rect& work_area = display_.work_area(); | |
| 67 gfx::Point anchor; | |
| 68 switch (shelf_edge) { | |
| 69 case SCREEN_EDGE_LEFT: | |
| 70 anchor = gfx::Point(work_area.x(), screen_rect.y()); | |
| 71 break; | |
| 72 case SCREEN_EDGE_RIGHT: | |
| 73 anchor = gfx::Point(work_area.right(), screen_rect.y()); | |
| 74 break; | |
| 75 case SCREEN_EDGE_TOP: | |
| 76 anchor = gfx::Point(screen_rect.x(), work_area.y()); | |
| 77 break; | |
| 78 case SCREEN_EDGE_BOTTOM: | |
| 79 anchor = gfx::Point(screen_rect.x(), work_area.bottom()); | |
| 80 break; | |
| 81 default: | |
| 82 NOTREACHED(); | |
| 83 anchor = gfx::Point(); | |
| 84 } | |
| 85 return ClampAnchorPoint(anchor); | |
| 86 } | |
| 87 | |
| 88 gfx::Point AppListPositioner::GetAnchorPointForShelfCenter( | |
| 89 ScreenEdge shelf_edge) const { | |
| 90 const gfx::Rect& work_area = display_.work_area(); | |
| 91 gfx::Point anchor; | |
| 92 switch (shelf_edge) { | |
| 93 case SCREEN_EDGE_LEFT: | |
| 94 anchor = | |
| 95 gfx::Point(work_area.x(), work_area.y() + work_area.height() / 2); | |
| 96 break; | |
| 97 case SCREEN_EDGE_RIGHT: | |
| 98 anchor = | |
| 99 gfx::Point(work_area.right(), work_area.y() + work_area.height() / 2); | |
| 100 break; | |
| 101 case SCREEN_EDGE_TOP: | |
| 102 anchor = gfx::Point(work_area.x() + work_area.width() / 2, work_area.y()); | |
| 103 break; | |
| 104 case SCREEN_EDGE_BOTTOM: | |
| 105 anchor = | |
| 106 gfx::Point(work_area.x() + work_area.width() / 2, work_area.bottom()); | |
| 107 break; | |
| 108 default: | |
| 109 NOTREACHED(); | |
| 110 anchor = gfx::Point(); | |
| 111 } | |
| 112 return ClampAnchorPoint(anchor); | |
| 113 } | |
| 114 | |
| 115 gfx::Point AppListPositioner::GetAnchorPointForShelfCursor( | |
| 116 ScreenEdge shelf_edge, | |
| 117 const gfx::Point& cursor) const { | |
| 118 const gfx::Rect& work_area = display_.work_area(); | |
| 119 gfx::Point anchor; | |
| 120 switch (shelf_edge) { | |
| 121 case SCREEN_EDGE_LEFT: | |
| 122 anchor = gfx::Point(work_area.x(), cursor.y()); | |
| 123 break; | |
| 124 case SCREEN_EDGE_RIGHT: | |
| 125 anchor = gfx::Point(work_area.right(), cursor.y()); | |
| 126 break; | |
| 127 case SCREEN_EDGE_TOP: | |
| 128 anchor = gfx::Point(cursor.x(), work_area.y()); | |
| 129 break; | |
| 130 case SCREEN_EDGE_BOTTOM: | |
| 131 anchor = gfx::Point(cursor.x(), work_area.bottom()); | |
| 132 break; | |
| 133 default: | |
| 134 NOTREACHED(); | |
| 135 anchor = gfx::Point(); | |
| 136 } | |
| 137 return ClampAnchorPoint(anchor); | |
| 138 } | |
| 139 | |
| 140 AppListPositioner::ScreenEdge AppListPositioner::GetShelfEdge( | |
| 141 const gfx::Rect& shelf_rect) const { | |
| 142 const gfx::Rect& screen_rect = display_.bounds(); | |
| 143 const gfx::Rect& work_area = display_.work_area(); | |
| 144 | |
| 145 // If we can't find the shelf, return SCREEN_EDGE_UNKNOWN. If the display | |
| 146 // size is the same as the work area, and does not contain the shelf, either | |
| 147 // the shelf is hidden or on another monitor. | |
| 148 if (work_area == screen_rect && !work_area.Contains(shelf_rect)) | |
| 149 return SCREEN_EDGE_UNKNOWN; | |
| 150 | |
| 151 // Note: On Windows 8 the work area won't include split windows on the left or | |
| 152 // right, and neither will |shelf_rect|. | |
| 153 if (shelf_rect.x() == work_area.x() && | |
| 154 shelf_rect.width() == work_area.width()) { | |
| 155 // Shelf is horizontal. | |
| 156 if (shelf_rect.bottom() == screen_rect.bottom()) | |
| 157 return SCREEN_EDGE_BOTTOM; | |
| 158 else if (shelf_rect.y() == screen_rect.y()) | |
| 159 return SCREEN_EDGE_TOP; | |
| 160 } else if (shelf_rect.y() == work_area.y() && | |
| 161 shelf_rect.height() == work_area.height()) { | |
| 162 // Shelf is vertical. | |
| 163 if (shelf_rect.x() == screen_rect.x()) | |
| 164 return SCREEN_EDGE_LEFT; | |
| 165 else if (shelf_rect.right() == screen_rect.right()) | |
| 166 return SCREEN_EDGE_RIGHT; | |
| 167 } | |
| 168 | |
| 169 return SCREEN_EDGE_UNKNOWN; | |
| 170 } | |
| 171 | |
| 172 int AppListPositioner::GetCursorDistanceFromShelf( | |
| 173 ScreenEdge shelf_edge, | |
| 174 const gfx::Point& cursor) const { | |
| 175 const gfx::Rect& work_area = display_.work_area(); | |
| 176 switch (shelf_edge) { | |
| 177 case SCREEN_EDGE_UNKNOWN: | |
| 178 return 0; | |
| 179 case SCREEN_EDGE_LEFT: | |
| 180 return std::max(0, cursor.x() - work_area.x()); | |
| 181 case SCREEN_EDGE_RIGHT: | |
| 182 return std::max(0, work_area.right() - cursor.x()); | |
| 183 case SCREEN_EDGE_TOP: | |
| 184 return std::max(0, cursor.y() - work_area.y()); | |
| 185 case SCREEN_EDGE_BOTTOM: | |
| 186 return std::max(0, work_area.bottom() - cursor.y()); | |
| 187 default: | |
| 188 NOTREACHED(); | |
| 189 return 0; | |
| 190 } | |
| 191 } | |
| 192 | |
| 193 gfx::Point AppListPositioner::ClampAnchorPoint(gfx::Point anchor) const { | |
| 194 gfx::Rect bounds_rect(display_.work_area()); | |
| 195 | |
| 196 // Anchor the center of the window in a region that prevents the window | |
| 197 // showing outside of the work area. | |
| 198 bounds_rect.Inset(window_size_.width() / 2 + min_distance_from_edge_, | |
| 199 window_size_.height() / 2 + min_distance_from_edge_); | |
| 200 | |
| 201 anchor.SetToMax(bounds_rect.origin()); | |
| 202 anchor.SetToMin(bounds_rect.bottom_right()); | |
| 203 return anchor; | |
| 204 } | |
| OLD | NEW |