| 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/workspace/workspace_window_resizer.h" | 5 #include "ash/wm/workspace/workspace_window_resizer.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 window, point_in_parent, window_component, source); | 88 window, point_in_parent, window_component, source); |
| 89 } | 89 } |
| 90 if (window_resizer) { | 90 if (window_resizer) { |
| 91 window_resizer = internal::DragWindowResizer::Create( | 91 window_resizer = internal::DragWindowResizer::Create( |
| 92 window_resizer, window, point_in_parent, window_component, source); | 92 window_resizer, window, point_in_parent, window_component, source); |
| 93 } | 93 } |
| 94 if (window_resizer && window->type() == aura::client::WINDOW_TYPE_PANEL) { | 94 if (window_resizer && window->type() == aura::client::WINDOW_TYPE_PANEL) { |
| 95 window_resizer = PanelWindowResizer::Create( | 95 window_resizer = PanelWindowResizer::Create( |
| 96 window_resizer, window, point_in_parent, window_component, source); | 96 window_resizer, window, point_in_parent, window_component, source); |
| 97 } | 97 } |
| 98 if (CommandLine::ForCurrentProcess()->HasSwitch( | 98 if (switches::UseDockedWindows() && |
| 99 switches::kAshEnableDockedWindows) && | |
| 100 window_resizer && window->parent() && | 99 window_resizer && window->parent() && |
| 101 !window->transient_parent() && | 100 !window->transient_parent() && |
| 102 (window->parent()->id() == internal::kShellWindowId_DefaultContainer || | 101 (window->parent()->id() == internal::kShellWindowId_DefaultContainer || |
| 103 window->parent()->id() == internal::kShellWindowId_DockedContainer || | 102 window->parent()->id() == internal::kShellWindowId_DockedContainer || |
| 104 window->parent()->id() == internal::kShellWindowId_PanelContainer)) { | 103 window->parent()->id() == internal::kShellWindowId_PanelContainer)) { |
| 105 window_resizer = internal::DockedWindowResizer::Create( | 104 window_resizer = internal::DockedWindowResizer::Create( |
| 106 window_resizer, window, point_in_parent, window_component, source); | 105 window_resizer, window, point_in_parent, window_component, source); |
| 107 } | 106 } |
| 108 window_state->set_window_resizer_(window_resizer); | 107 window_state->set_window_resizer_(window_resizer); |
| 109 return make_scoped_ptr<WindowResizer>(window_resizer); | 108 return make_scoped_ptr<WindowResizer>(window_resizer); |
| 110 } | 109 } |
| 111 | 110 |
| 112 namespace internal { | 111 namespace internal { |
| 113 | 112 |
| 114 namespace { | 113 namespace { |
| 115 | 114 |
| 116 // Snapping distance used instead of WorkspaceWindowResizer::kScreenEdgeInset | 115 // Snapping distance used instead of WorkspaceWindowResizer::kScreenEdgeInset |
| 117 // when resizing a window using touchscreen. | 116 // when resizing a window using touchscreen. |
| 118 const int kScreenEdgeInsetForTouchResize = 32; | 117 const int kScreenEdgeInsetForTouchResize = 32; |
| 119 | 118 |
| 120 // Returns true if the window should stick to the edge. | |
| 121 bool ShouldStickToEdge(int distance_from_edge, int sticky_size) { | |
| 122 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 123 switches::kAshEnableStickyEdges) || | |
| 124 CommandLine::ForCurrentProcess()->HasSwitch( | |
| 125 switches::kAshEnableDockedWindows)) { | |
| 126 return distance_from_edge < 0 && | |
| 127 distance_from_edge > -sticky_size; | |
| 128 } | |
| 129 return distance_from_edge < sticky_size && | |
| 130 distance_from_edge > -sticky_size * 2; | |
| 131 } | |
| 132 | |
| 133 // Returns the coordinate along the secondary axis to snap to. | 119 // Returns the coordinate along the secondary axis to snap to. |
| 134 int CoordinateAlongSecondaryAxis(SecondaryMagnetismEdge edge, | 120 int CoordinateAlongSecondaryAxis(SecondaryMagnetismEdge edge, |
| 135 int leading, | 121 int leading, |
| 136 int trailing, | 122 int trailing, |
| 137 int none) { | 123 int none) { |
| 138 switch (edge) { | 124 switch (edge) { |
| 139 case SECONDARY_MAGNETISM_EDGE_LEADING: | 125 case SECONDARY_MAGNETISM_EDGE_LEADING: |
| 140 return leading; | 126 return leading; |
| 141 case SECONDARY_MAGNETISM_EDGE_TRAILING: | 127 case SECONDARY_MAGNETISM_EDGE_TRAILING: |
| 142 return trailing; | 128 return trailing; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 | 252 |
| 267 // static | 253 // static |
| 268 const int WorkspaceWindowResizer::kMinOnscreenHeight = 32; | 254 const int WorkspaceWindowResizer::kMinOnscreenHeight = 32; |
| 269 | 255 |
| 270 // static | 256 // static |
| 271 const int WorkspaceWindowResizer::kScreenEdgeInset = 8; | 257 const int WorkspaceWindowResizer::kScreenEdgeInset = 8; |
| 272 | 258 |
| 273 // static | 259 // static |
| 274 const int WorkspaceWindowResizer::kStickyDistancePixels = 64; | 260 const int WorkspaceWindowResizer::kStickyDistancePixels = 64; |
| 275 | 261 |
| 262 // static |
| 263 WorkspaceWindowResizer* WorkspaceWindowResizer::instance_ = NULL; |
| 264 |
| 276 // Represents the width or height of a window with constraints on its minimum | 265 // Represents the width or height of a window with constraints on its minimum |
| 277 // and maximum size. 0 represents a lack of a constraint. | 266 // and maximum size. 0 represents a lack of a constraint. |
| 278 class WindowSize { | 267 class WindowSize { |
| 279 public: | 268 public: |
| 280 WindowSize(int size, int min, int max) | 269 WindowSize(int size, int min, int max) |
| 281 : size_(size), | 270 : size_(size), |
| 282 min_(min), | 271 min_(min), |
| 283 max_(max) { | 272 max_(max) { |
| 284 // Grow the min/max bounds to include the starting size. | 273 // Grow the min/max bounds to include the starting size. |
| 285 if (is_underflowing()) | 274 if (is_underflowing()) |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 | 327 |
| 339 private: | 328 private: |
| 340 int size_; | 329 int size_; |
| 341 int min_; | 330 int min_; |
| 342 int max_; | 331 int max_; |
| 343 }; | 332 }; |
| 344 | 333 |
| 345 WorkspaceWindowResizer::~WorkspaceWindowResizer() { | 334 WorkspaceWindowResizer::~WorkspaceWindowResizer() { |
| 346 Shell* shell = Shell::GetInstance(); | 335 Shell* shell = Shell::GetInstance(); |
| 347 shell->cursor_manager()->UnlockCursor(); | 336 shell->cursor_manager()->UnlockCursor(); |
| 337 if (instance_ == this) |
| 338 instance_ = NULL; |
| 348 } | 339 } |
| 349 | 340 |
| 350 // static | 341 // static |
| 351 WorkspaceWindowResizer* WorkspaceWindowResizer::Create( | 342 WorkspaceWindowResizer* WorkspaceWindowResizer::Create( |
| 352 aura::Window* window, | 343 aura::Window* window, |
| 353 const gfx::Point& location_in_parent, | 344 const gfx::Point& location_in_parent, |
| 354 int window_component, | 345 int window_component, |
| 355 aura::client::WindowMoveSource source, | 346 aura::client::WindowMoveSource source, |
| 356 const std::vector<aura::Window*>& attached_windows) { | 347 const std::vector<aura::Window*>& attached_windows) { |
| 357 Details details(window, location_in_parent, window_component, source); | 348 Details details(window, location_in_parent, window_component, source); |
| 358 return details.is_resizable ? | 349 return details.is_resizable ? |
| 359 new WorkspaceWindowResizer(details, attached_windows) : NULL; | 350 new WorkspaceWindowResizer(details, attached_windows) : NULL; |
| 360 } | 351 } |
| 361 | 352 |
| 362 void WorkspaceWindowResizer::Drag(const gfx::Point& location_in_parent, | 353 void WorkspaceWindowResizer::Drag(const gfx::Point& location_in_parent, |
| 363 int event_flags) { | 354 int event_flags) { |
| 364 last_mouse_location_ = location_in_parent; | 355 last_mouse_location_ = location_in_parent; |
| 365 | 356 |
| 366 int sticky_size; | 357 int sticky_size; |
| 367 if (event_flags & ui::EF_CONTROL_DOWN) { | 358 if (event_flags & ui::EF_CONTROL_DOWN) { |
| 368 sticky_size = 0; | 359 sticky_size = 0; |
| 369 } else if (CommandLine::ForCurrentProcess()->HasSwitch( | 360 } else if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 370 switches::kAshEnableStickyEdges) || | 361 switches::kAshEnableStickyEdges)) { |
| 371 CommandLine::ForCurrentProcess()->HasSwitch( | |
| 372 switches::kAshEnableDockedWindows)) { | |
| 373 sticky_size = kStickyDistancePixels; | 362 sticky_size = kStickyDistancePixels; |
| 374 } else if ((details_.bounds_change & kBoundsChange_Resizes) && | 363 } else if ((details_.bounds_change & kBoundsChange_Resizes) && |
| 375 details_.source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) { | 364 details_.source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) { |
| 376 sticky_size = kScreenEdgeInsetForTouchResize; | 365 sticky_size = kScreenEdgeInsetForTouchResize; |
| 377 } else { | 366 } else { |
| 378 sticky_size = kScreenEdgeInset; | 367 sticky_size = kScreenEdgeInset; |
| 379 } | 368 } |
| 380 // |bounds| is in |window()->parent()|'s coordinates. | 369 // |bounds| is in |window()->parent()|'s coordinates. |
| 381 gfx::Rect bounds = CalculateBoundsForDrag(details_, location_in_parent); | 370 gfx::Rect bounds = CalculateBoundsForDrag(details_, location_in_parent); |
| 382 if (window_state()->IsNormalShowState()) | 371 if (window_state()->IsNormalShowState()) |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 int initial_size = PrimaryAxisSize(attached_windows_[i]->bounds().size()); | 524 int initial_size = PrimaryAxisSize(attached_windows_[i]->bounds().size()); |
| 536 initial_size_.push_back(initial_size); | 525 initial_size_.push_back(initial_size); |
| 537 // If current size is smaller than the min, use the current size as the min. | 526 // If current size is smaller than the min, use the current size as the min. |
| 538 // This way we don't snap on resize. | 527 // This way we don't snap on resize. |
| 539 int min_size = std::min(initial_size, | 528 int min_size = std::min(initial_size, |
| 540 std::max(PrimaryAxisSize(min), kMinOnscreenSize)); | 529 std::max(PrimaryAxisSize(min), kMinOnscreenSize)); |
| 541 total_min_ += min_size; | 530 total_min_ += min_size; |
| 542 total_initial_size_ += initial_size; | 531 total_initial_size_ += initial_size; |
| 543 total_available += std::max(min_size, initial_size) - min_size; | 532 total_available += std::max(min_size, initial_size) - min_size; |
| 544 } | 533 } |
| 534 instance_ = this; |
| 545 } | 535 } |
| 546 | 536 |
| 547 gfx::Rect WorkspaceWindowResizer::GetFinalBounds( | 537 gfx::Rect WorkspaceWindowResizer::GetFinalBounds( |
| 548 const gfx::Rect& bounds) const { | 538 const gfx::Rect& bounds) const { |
| 549 if (snap_phantom_window_controller_.get() && | 539 if (snap_phantom_window_controller_.get() && |
| 550 snap_phantom_window_controller_->IsShowing()) { | 540 snap_phantom_window_controller_->IsShowing()) { |
| 551 return snap_phantom_window_controller_->bounds_in_screen(); | 541 return snap_phantom_window_controller_->bounds_in_screen(); |
| 552 } | 542 } |
| 553 return bounds; | 543 return bounds; |
| 554 } | 544 } |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 811 if (details_.window_component == HTRIGHT) { | 801 if (details_.window_component == HTRIGHT) { |
| 812 bounds->set_width(std::min(bounds->width(), | 802 bounds->set_width(std::min(bounds->width(), |
| 813 work_area.right() - total_min_ - bounds->x())); | 803 work_area.right() - total_min_ - bounds->x())); |
| 814 } else { | 804 } else { |
| 815 DCHECK_EQ(HTBOTTOM, details_.window_component); | 805 DCHECK_EQ(HTBOTTOM, details_.window_component); |
| 816 bounds->set_height(std::min(bounds->height(), | 806 bounds->set_height(std::min(bounds->height(), |
| 817 work_area.bottom() - total_min_ - bounds->y())); | 807 work_area.bottom() - total_min_ - bounds->y())); |
| 818 } | 808 } |
| 819 } | 809 } |
| 820 | 810 |
| 811 bool WorkspaceWindowResizer::ShouldStickToEdge(int distance_from_edge, |
| 812 int sticky_size) const { |
| 813 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 814 switches::kAshEnableStickyEdges)) { |
| 815 int snapping_distance = 0; |
| 816 if ((details_.bounds_change & kBoundsChange_Resizes) && |
| 817 details_.source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) { |
| 818 snapping_distance = sticky_size / 2; |
| 819 } |
| 820 return distance_from_edge < snapping_distance && |
| 821 distance_from_edge > -sticky_size; |
| 822 } |
| 823 return distance_from_edge < sticky_size && |
| 824 distance_from_edge > -sticky_size * 2; |
| 825 } |
| 826 |
| 821 bool WorkspaceWindowResizer::StickToWorkAreaOnMove( | 827 bool WorkspaceWindowResizer::StickToWorkAreaOnMove( |
| 822 const gfx::Rect& work_area, | 828 const gfx::Rect& work_area, |
| 823 int sticky_size, | 829 int sticky_size, |
| 824 gfx::Rect* bounds) const { | 830 gfx::Rect* bounds) const { |
| 825 const int left_edge = work_area.x(); | 831 const int left_edge = work_area.x(); |
| 826 const int right_edge = work_area.right(); | 832 const int right_edge = work_area.right(); |
| 827 const int top_edge = work_area.y(); | 833 const int top_edge = work_area.y(); |
| 828 const int bottom_edge = work_area.bottom(); | 834 const int bottom_edge = work_area.bottom(); |
| 829 bool updated = false; | 835 bool updated = false; |
| 830 if (ShouldStickToEdge(bounds->x() - left_edge, sticky_size)) { | 836 if (ShouldStickToEdge(bounds->x() - left_edge, sticky_size)) { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 if (!dock_layout_->is_dragged_window_docked()) | 1015 if (!dock_layout_->is_dragged_window_docked()) |
| 1010 dock_layout_->DockDraggedWindow(window()); | 1016 dock_layout_->DockDraggedWindow(window()); |
| 1011 } else { | 1017 } else { |
| 1012 if (dock_layout_->is_dragged_window_docked()) | 1018 if (dock_layout_->is_dragged_window_docked()) |
| 1013 dock_layout_->UndockDraggedWindow(); | 1019 dock_layout_->UndockDraggedWindow(); |
| 1014 } | 1020 } |
| 1015 } | 1021 } |
| 1016 | 1022 |
| 1017 } // namespace internal | 1023 } // namespace internal |
| 1018 } // namespace ash | 1024 } // namespace ash |
| OLD | NEW |