| 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 |