OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/wm/window_resizer.h" | 5 #include "ash/wm/window_resizer.h" |
6 | 6 |
7 #include "ash/screen_ash.h" | 7 #include "ash/screen_ash.h" |
8 #include "ash/shell.h" | 8 #include "ash/shell.h" |
9 #include "ui/aura/client/aura_constants.h" | 9 #include "ui/aura/client/aura_constants.h" |
10 #include "ui/aura/root_window.h" | 10 #include "ui/aura/root_window.h" |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 case HTGROWBOX: | 153 case HTGROWBOX: |
154 bounds_change |= WindowResizer::kBoundsChange_Resizes; | 154 bounds_change |= WindowResizer::kBoundsChange_Resizes; |
155 break; | 155 break; |
156 default: | 156 default: |
157 break; | 157 break; |
158 } | 158 } |
159 return bounds_change; | 159 return bounds_change; |
160 } | 160 } |
161 | 161 |
162 // static | 162 // static |
163 int WindowResizer::AlignToGrid(int location, int grid_size) { | |
164 if (grid_size <= 1 || location % grid_size == 0) | |
165 return location; | |
166 return floor(static_cast<float>(location) / static_cast<float>(grid_size) + | |
167 .5f) * grid_size; | |
168 } | |
169 | |
170 // static | |
171 int WindowResizer::AlignToGridRoundUp(int location, int grid_size) { | |
172 if (grid_size <= 1 || location % grid_size == 0) | |
173 return location; | |
174 return (location / grid_size + 1) * grid_size; | |
175 } | |
176 | |
177 // static | |
178 int WindowResizer::AlignToGridRoundDown(int location, int grid_size) { | |
179 if (grid_size <= 1 || location % grid_size == 0) | |
180 return location; | |
181 return location / grid_size * grid_size; | |
182 } | |
183 | |
184 // static | |
185 gfx::Rect WindowResizer::CalculateBoundsForDrag( | 163 gfx::Rect WindowResizer::CalculateBoundsForDrag( |
186 const Details& details, | 164 const Details& details, |
187 const gfx::Point& location, | 165 const gfx::Point& location) { |
188 int grid_size) { | |
189 if (!details.is_resizable) | 166 if (!details.is_resizable) |
190 return details.initial_bounds; | 167 return details.initial_bounds; |
191 | 168 |
192 int delta_x = location.x() - details.initial_location_in_parent.x(); | 169 int delta_x = location.x() - details.initial_location_in_parent.x(); |
193 int delta_y = location.y() - details.initial_location_in_parent.y(); | 170 int delta_y = location.y() - details.initial_location_in_parent.y(); |
194 | 171 |
195 // The minimize size constraint may limit how much we change the window | 172 // The minimize size constraint may limit how much we change the window |
196 // position. For example, dragging the left edge to the right should stop | 173 // position. For example, dragging the left edge to the right should stop |
197 // repositioning the window when the minimize size is reached. | 174 // repositioning the window when the minimize size is reached. |
198 gfx::Size size = GetSizeForDrag(details, &delta_x, &delta_y, grid_size); | 175 gfx::Size size = GetSizeForDrag(details, &delta_x, &delta_y); |
199 gfx::Point origin = GetOriginForDrag(details, delta_x, delta_y); | 176 gfx::Point origin = GetOriginForDrag(details, delta_x, delta_y); |
200 | 177 |
201 gfx::Rect new_bounds(origin, size); | 178 gfx::Rect new_bounds(origin, size); |
202 // Update bottom edge to stay in the work area when we are resizing | 179 // Update bottom edge to stay in the work area when we are resizing |
203 // by dragging the bottome edge or corners. | 180 // by dragging the bottome edge or corners. |
204 if (details.window_component == HTBOTTOM || | 181 if (details.window_component == HTBOTTOM || |
205 details.window_component == HTBOTTOMRIGHT || | 182 details.window_component == HTBOTTOMRIGHT || |
206 details.window_component == HTBOTTOMLEFT) { | 183 details.window_component == HTBOTTOMLEFT) { |
207 gfx::Rect work_area = | 184 gfx::Rect work_area = |
208 ScreenAsh::GetDisplayWorkAreaBoundsInParent(details.window); | 185 ScreenAsh::GetDisplayWorkAreaBoundsInParent(details.window); |
209 if (new_bounds.bottom() > work_area.bottom()) | 186 if (new_bounds.bottom() > work_area.bottom()) |
210 new_bounds.Inset(0, 0, 0, | 187 new_bounds.Inset(0, 0, 0, |
211 new_bounds.bottom() - work_area.bottom()); | 188 new_bounds.bottom() - work_area.bottom()); |
212 } | 189 } |
213 if (details.bounds_change & kBoundsChange_Resizes && | 190 if (details.bounds_change & kBoundsChange_Resizes && |
214 details.bounds_change & kBoundsChange_Repositions && new_bounds.y() < 0) { | 191 details.bounds_change & kBoundsChange_Repositions && new_bounds.y() < 0) { |
215 int delta = new_bounds.y(); | 192 int delta = new_bounds.y(); |
216 new_bounds.set_y(0); | 193 new_bounds.set_y(0); |
217 new_bounds.set_height(new_bounds.height() + delta); | 194 new_bounds.set_height(new_bounds.height() + delta); |
218 } | 195 } |
219 return new_bounds; | 196 return new_bounds; |
220 } | 197 } |
221 | 198 |
222 // static | 199 // static |
223 gfx::Rect WindowResizer::AdjustBoundsToGrid(const gfx::Rect& bounds, | |
224 int grid_size) { | |
225 if (grid_size <= 1) | |
226 return bounds; | |
227 int x = AlignToGrid(bounds.x(), grid_size); | |
228 int y = AlignToGrid(bounds.y(), grid_size); | |
229 return gfx::Rect(x, y, bounds.width(), bounds.height()); | |
230 } | |
231 | |
232 // static | |
233 bool WindowResizer::IsBottomEdge(int window_component) { | 200 bool WindowResizer::IsBottomEdge(int window_component) { |
234 return window_component == HTBOTTOMLEFT || | 201 return window_component == HTBOTTOMLEFT || |
235 window_component == HTBOTTOM || | 202 window_component == HTBOTTOM || |
236 window_component == HTBOTTOMRIGHT || | 203 window_component == HTBOTTOMRIGHT || |
237 window_component == HTGROWBOX; | 204 window_component == HTGROWBOX; |
238 } | 205 } |
239 | 206 |
240 // static | 207 // static |
241 gfx::Point WindowResizer::GetOriginForDrag(const Details& details, | 208 gfx::Point WindowResizer::GetOriginForDrag(const Details& details, |
242 int delta_x, | 209 int delta_x, |
243 int delta_y) { | 210 int delta_y) { |
244 gfx::Point origin = details.initial_bounds.origin(); | 211 gfx::Point origin = details.initial_bounds.origin(); |
245 if (details.bounds_change & kBoundsChange_Repositions) { | 212 if (details.bounds_change & kBoundsChange_Repositions) { |
246 int pos_change_direction = | 213 int pos_change_direction = |
247 GetPositionChangeDirectionForWindowComponent(details.window_component); | 214 GetPositionChangeDirectionForWindowComponent(details.window_component); |
248 if (pos_change_direction & kBoundsChangeDirection_Horizontal) | 215 if (pos_change_direction & kBoundsChangeDirection_Horizontal) |
249 origin.Offset(delta_x, 0); | 216 origin.Offset(delta_x, 0); |
250 if (pos_change_direction & kBoundsChangeDirection_Vertical) | 217 if (pos_change_direction & kBoundsChangeDirection_Vertical) |
251 origin.Offset(0, delta_y); | 218 origin.Offset(0, delta_y); |
252 } | 219 } |
253 return origin; | 220 return origin; |
254 } | 221 } |
255 | 222 |
256 // static | 223 // static |
257 gfx::Size WindowResizer::GetSizeForDrag(const Details& details, | 224 gfx::Size WindowResizer::GetSizeForDrag(const Details& details, |
258 int* delta_x, | 225 int* delta_x, |
259 int* delta_y, | 226 int* delta_y) { |
260 int grid_size) { | |
261 gfx::Size size = details.initial_bounds.size(); | 227 gfx::Size size = details.initial_bounds.size(); |
262 if (details.bounds_change & kBoundsChange_Resizes) { | 228 if (details.bounds_change & kBoundsChange_Resizes) { |
263 gfx::Size min_size = details.window->delegate()->GetMinimumSize(); | 229 gfx::Size min_size = details.window->delegate()->GetMinimumSize(); |
264 min_size.set_width(AlignToGridRoundUp(min_size.width(), grid_size)); | 230 size.SetSize(GetWidthForDrag(details, min_size.width(), delta_x), |
265 min_size.set_height(AlignToGridRoundUp(min_size.height(), grid_size)); | 231 GetHeightForDrag(details, min_size.height(), delta_y)); |
266 size.SetSize(GetWidthForDrag(details, min_size.width(), delta_x, | |
267 grid_size), | |
268 GetHeightForDrag(details, min_size.height(), delta_y, | |
269 grid_size)); | |
270 } | 232 } |
271 return size; | 233 return size; |
272 } | 234 } |
273 | 235 |
274 // static | 236 // static |
275 int WindowResizer::GetWidthForDrag(const Details& details, | 237 int WindowResizer::GetWidthForDrag(const Details& details, |
276 int min_width, | 238 int min_width, |
277 int* delta_x, | 239 int* delta_x) { |
278 int grid_size) { | |
279 int width = details.initial_bounds.width(); | 240 int width = details.initial_bounds.width(); |
280 if (details.size_change_direction & kBoundsChangeDirection_Horizontal) { | 241 if (details.size_change_direction & kBoundsChangeDirection_Horizontal) { |
281 // Along the right edge, positive delta_x increases the window size. | 242 // Along the right edge, positive delta_x increases the window size. |
282 int x_multiplier = IsRightEdge(details.window_component) ? 1 : -1; | 243 int x_multiplier = IsRightEdge(details.window_component) ? 1 : -1; |
283 width += x_multiplier * (*delta_x); | 244 width += x_multiplier * (*delta_x); |
284 int adjusted_width = AlignToGrid(width, grid_size); | |
285 if (adjusted_width != width) { | |
286 *delta_x += -x_multiplier * (width - adjusted_width); | |
287 width = adjusted_width; | |
288 } | |
289 | 245 |
290 // Ensure we don't shrink past the minimum width and clamp delta_x | 246 // Ensure we don't shrink past the minimum width and clamp delta_x |
291 // for the window origin computation. | 247 // for the window origin computation. |
292 if (width < min_width) { | 248 if (width < min_width) { |
293 width = min_width; | 249 width = min_width; |
294 *delta_x = -x_multiplier * (details.initial_bounds.width() - min_width); | 250 *delta_x = -x_multiplier * (details.initial_bounds.width() - min_width); |
295 } | 251 } |
296 | 252 |
297 // And don't let the window go bigger than the display. | 253 // And don't let the window go bigger than the display. |
298 int max_width = | 254 int max_width = |
299 gfx::Screen::GetDisplayNearestWindow(details.window).bounds().width(); | 255 gfx::Screen::GetDisplayNearestWindow(details.window).bounds().width(); |
300 if (width > max_width) { | 256 if (width > max_width) { |
301 width = max_width; | 257 width = max_width; |
302 *delta_x = -x_multiplier * (details.initial_bounds.width() - max_width); | 258 *delta_x = -x_multiplier * (details.initial_bounds.width() - max_width); |
303 } | 259 } |
304 } | 260 } |
305 return width; | 261 return width; |
306 } | 262 } |
307 | 263 |
308 // static | 264 // static |
309 int WindowResizer::GetHeightForDrag(const Details& details, | 265 int WindowResizer::GetHeightForDrag(const Details& details, |
310 int min_height, | 266 int min_height, |
311 int* delta_y, | 267 int* delta_y) { |
312 int grid_size) { | |
313 int height = details.initial_bounds.height(); | 268 int height = details.initial_bounds.height(); |
314 if (details.size_change_direction & kBoundsChangeDirection_Vertical) { | 269 if (details.size_change_direction & kBoundsChangeDirection_Vertical) { |
315 // Along the bottom edge, positive delta_y increases the window size. | 270 // Along the bottom edge, positive delta_y increases the window size. |
316 int y_multiplier = IsBottomEdge(details.window_component) ? 1 : -1; | 271 int y_multiplier = IsBottomEdge(details.window_component) ? 1 : -1; |
317 height += y_multiplier * (*delta_y); | 272 height += y_multiplier * (*delta_y); |
318 int adjusted_height = AlignToGrid(height, grid_size); | |
319 if (height != adjusted_height) { | |
320 *delta_y += -y_multiplier * (height - adjusted_height); | |
321 height = adjusted_height; | |
322 } | |
323 | 273 |
324 // Ensure we don't shrink past the minimum height and clamp delta_y | 274 // Ensure we don't shrink past the minimum height and clamp delta_y |
325 // for the window origin computation. | 275 // for the window origin computation. |
326 if (height < min_height) { | 276 if (height < min_height) { |
327 height = min_height; | 277 height = min_height; |
328 *delta_y = -y_multiplier * (details.initial_bounds.height() - min_height); | 278 *delta_y = -y_multiplier * (details.initial_bounds.height() - min_height); |
329 } | 279 } |
330 | 280 |
331 // And don't let the window go bigger than the display. | 281 // And don't let the window go bigger than the display. |
332 int max_height = | 282 int max_height = |
333 gfx::Screen::GetDisplayNearestWindow(details.window).bounds().height(); | 283 gfx::Screen::GetDisplayNearestWindow(details.window).bounds().height(); |
334 if (height > max_height) { | 284 if (height > max_height) { |
335 height = max_height; | 285 height = max_height; |
336 *delta_y = -y_multiplier * (details.initial_bounds.height() - max_height); | 286 *delta_y = -y_multiplier * (details.initial_bounds.height() - max_height); |
337 } | 287 } |
338 } | 288 } |
339 return height; | 289 return height; |
340 } | 290 } |
341 | 291 |
342 } // namespace aura | 292 } // namespace aura |
OLD | NEW |