| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef ASH_WM_WORKSPACE_WORKSPACE_WINDOW_RESIZER_H_ | |
| 6 #define ASH_WM_WORKSPACE_WORKSPACE_WINDOW_RESIZER_H_ | |
| 7 | |
| 8 #include <stdint.h> | |
| 9 | |
| 10 #include <memory> | |
| 11 #include <vector> | |
| 12 | |
| 13 #include "ash/wm/common/window_resizer.h" | |
| 14 #include "ash/wm/common/wm_window_tracker.h" | |
| 15 #include "ash/wm/workspace/magnetism_matcher.h" | |
| 16 #include "base/compiler_specific.h" | |
| 17 #include "base/macros.h" | |
| 18 #include "base/memory/weak_ptr.h" | |
| 19 | |
| 20 namespace ash { | |
| 21 class DockedWindowLayoutManager; | |
| 22 class PhantomWindowController; | |
| 23 class TwoStepEdgeCycler; | |
| 24 class WindowSize; | |
| 25 | |
| 26 namespace wm { | |
| 27 class WindowState; | |
| 28 class WmGlobals; | |
| 29 } | |
| 30 | |
| 31 // WindowResizer implementation for workspaces. This enforces that windows are | |
| 32 // not allowed to vertically move or resize outside of the work area. As windows | |
| 33 // are moved outside the work area they are shrunk. We remember the height of | |
| 34 // the window before it was moved so that if the window is again moved up we | |
| 35 // attempt to restore the old height. | |
| 36 class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer { | |
| 37 public: | |
| 38 // When dragging an attached window this is the min size we'll make sure is | |
| 39 // visible. In the vertical direction we take the max of this and that from | |
| 40 // the delegate. | |
| 41 static const int kMinOnscreenSize; | |
| 42 | |
| 43 // Min height we'll force on screen when dragging the caption. | |
| 44 // TODO: this should come from a property on the window. | |
| 45 static const int kMinOnscreenHeight; | |
| 46 | |
| 47 // Snap region when dragging close to the edges. That is, as the window gets | |
| 48 // this close to an edge of the screen it snaps to the edge. | |
| 49 static const int kScreenEdgeInset; | |
| 50 | |
| 51 // Distance in pixels that the cursor must move past an edge for a window | |
| 52 // to move or resize beyond that edge. | |
| 53 static const int kStickyDistancePixels; | |
| 54 | |
| 55 ~WorkspaceWindowResizer() override; | |
| 56 | |
| 57 static WorkspaceWindowResizer* Create( | |
| 58 wm::WindowState* window_state, | |
| 59 const std::vector<wm::WmWindow*>& attached_windows); | |
| 60 | |
| 61 // WindowResizer: | |
| 62 void Drag(const gfx::Point& location_in_parent, int event_flags) override; | |
| 63 void CompleteDrag() override; | |
| 64 void RevertDrag() override; | |
| 65 | |
| 66 private: | |
| 67 friend class WorkspaceWindowResizerTest; | |
| 68 | |
| 69 // The edge to which the window should be snapped at the end of the drag. | |
| 70 enum SnapType { SNAP_LEFT, SNAP_RIGHT, SNAP_NONE }; | |
| 71 | |
| 72 WorkspaceWindowResizer(wm::WindowState* window_state, | |
| 73 const std::vector<wm::WmWindow*>& attached_windows); | |
| 74 | |
| 75 // Lays out the attached windows. |bounds| is the bounds of the main window. | |
| 76 void LayoutAttachedWindows(gfx::Rect* bounds); | |
| 77 | |
| 78 // Calculates the new sizes of the attached windows, given that the main | |
| 79 // window has been resized (along the primary axis) by |delta|. | |
| 80 // |available_size| is the maximum length of the space that the attached | |
| 81 // windows are allowed to occupy (ie: the distance between the right/bottom | |
| 82 // edge of the primary window and the right/bottom of the desktop area). | |
| 83 // Populates |sizes| with the desired sizes of the attached windows, and | |
| 84 // returns the number of pixels that couldn't be allocated to the attached | |
| 85 // windows (due to min/max size constraints). | |
| 86 // Note the return value can be positive or negative, a negative value | |
| 87 // indicating that that many pixels couldn't be removed from the attached | |
| 88 // windows. | |
| 89 int CalculateAttachedSizes( | |
| 90 int delta, | |
| 91 int available_size, | |
| 92 std::vector<int>* sizes) const; | |
| 93 | |
| 94 // Divides |amount| evenly between |sizes|. If |amount| is negative it | |
| 95 // indicates how many pixels |sizes| should be shrunk by. | |
| 96 // Returns how many pixels failed to be allocated/removed from |sizes|. | |
| 97 int GrowFairly(int amount, std::vector<WindowSize>* sizes) const; | |
| 98 | |
| 99 // Calculate the ratio of pixels that each WindowSize in |sizes| should | |
| 100 // receive when growing or shrinking. | |
| 101 void CalculateGrowthRatios(const std::vector<WindowSize*>& sizes, | |
| 102 std::vector<float>* out_ratios) const; | |
| 103 | |
| 104 // Adds a WindowSize to |sizes| for each attached window. | |
| 105 void CreateBucketsForAttached(std::vector<WindowSize>* sizes) const; | |
| 106 | |
| 107 // If possible snaps the window to a neary window. Updates |bounds| if there | |
| 108 // was a close enough window. | |
| 109 void MagneticallySnapToOtherWindows(gfx::Rect* bounds); | |
| 110 | |
| 111 // If possible snaps the resize to a neary window. Updates |bounds| if there | |
| 112 // was a close enough window. | |
| 113 void MagneticallySnapResizeToOtherWindows(gfx::Rect* bounds); | |
| 114 | |
| 115 // Finds the neareset window to magentically snap to. Updates | |
| 116 // |magnetism_window_| and |magnetism_edge_| appropriately. |edges| is a | |
| 117 // bitmask of the MagnetismEdges to match again. Returns true if a match is | |
| 118 // found. | |
| 119 bool UpdateMagnetismWindow(const gfx::Rect& bounds, uint32_t edges); | |
| 120 | |
| 121 // Adjusts the bounds of the window: magnetically snapping, ensuring the | |
| 122 // window has enough on screen... |snap_size| is the distance from an edge of | |
| 123 // the work area before the window is snapped. A value of 0 results in no | |
| 124 // snapping. | |
| 125 void AdjustBoundsForMainWindow(int snap_size, gfx::Rect* bounds); | |
| 126 | |
| 127 // Stick the window bounds to the work area during a move. | |
| 128 bool StickToWorkAreaOnMove(const gfx::Rect& work_area, | |
| 129 int sticky_size, | |
| 130 gfx::Rect* bounds) const; | |
| 131 | |
| 132 // Stick the window bounds to the work area during a resize. | |
| 133 void StickToWorkAreaOnResize(const gfx::Rect& work_area, | |
| 134 int sticky_size, | |
| 135 gfx::Rect* bounds) const; | |
| 136 | |
| 137 // Returns a coordinate along the primary axis. Used to share code for | |
| 138 // left/right multi window resize and top/bottom resize. | |
| 139 int PrimaryAxisSize(const gfx::Size& size) const; | |
| 140 int PrimaryAxisCoordinate(int x, int y) const; | |
| 141 | |
| 142 // Updates the bounds of the phantom window for window snapping. | |
| 143 void UpdateSnapPhantomWindow(const gfx::Point& location, | |
| 144 const gfx::Rect& bounds); | |
| 145 | |
| 146 // Restacks the windows z-order position so that one of the windows is at the | |
| 147 // top of the z-order, and the rest directly underneath it. | |
| 148 void RestackWindows(); | |
| 149 | |
| 150 // Returns the edge to which the window should be snapped to if the user does | |
| 151 // no more dragging. SNAP_NONE is returned if the window should not be | |
| 152 // snapped. | |
| 153 SnapType GetSnapType(const gfx::Point& location) const; | |
| 154 | |
| 155 // Returns true if |bounds_in_parent| are valid bounds for snapped state type | |
| 156 // |snapped_type|. | |
| 157 bool AreBoundsValidSnappedBounds(wm::WindowStateType snapped_type, | |
| 158 const gfx::Rect& bounds_in_parent) const; | |
| 159 | |
| 160 // Docks or undocks the dragged window. | |
| 161 void SetDraggedWindowDocked(bool should_dock); | |
| 162 | |
| 163 wm::WindowState* window_state() { return window_state_; } | |
| 164 | |
| 165 const std::vector<wm::WmWindow*> attached_windows_; | |
| 166 | |
| 167 wm::WmGlobals* globals_; | |
| 168 | |
| 169 // Returns the currently used instance for test. | |
| 170 static WorkspaceWindowResizer* GetInstanceForTest(); | |
| 171 | |
| 172 bool did_lock_cursor_; | |
| 173 | |
| 174 // Set to true once Drag() is invoked and the bounds of the window change. | |
| 175 bool did_move_or_resize_; | |
| 176 | |
| 177 // True if the window initially had |bounds_changed_by_user_| set in state. | |
| 178 bool initial_bounds_changed_by_user_; | |
| 179 | |
| 180 // The initial size of each of the windows in |attached_windows_| along the | |
| 181 // primary axis. | |
| 182 std::vector<int> initial_size_; | |
| 183 | |
| 184 // Sum of the minimum sizes of the attached windows. | |
| 185 int total_min_; | |
| 186 | |
| 187 // Sum of the sizes in |initial_size_|. | |
| 188 int total_initial_size_; | |
| 189 | |
| 190 // Gives a previews of where the the window will end up. Only used if there | |
| 191 // is a grid and the caption is being dragged. | |
| 192 std::unique_ptr<PhantomWindowController> snap_phantom_window_controller_; | |
| 193 | |
| 194 // Used to determine whether the window should be snapped or docked when | |
| 195 // the user drags a window to the edge of the screen. | |
| 196 std::unique_ptr<TwoStepEdgeCycler> edge_cycler_; | |
| 197 | |
| 198 // The edge to which the window should be snapped to at the end of the drag. | |
| 199 SnapType snap_type_; | |
| 200 | |
| 201 // Number of mouse moves since the last bounds change. Only used for phantom | |
| 202 // placement to track when the mouse is moved while pushed against the edge of | |
| 203 // the screen. | |
| 204 int num_mouse_moves_since_bounds_change_; | |
| 205 | |
| 206 // The mouse location passed to Drag(). | |
| 207 gfx::Point last_mouse_location_; | |
| 208 | |
| 209 // Window the drag has magnetically attached to. | |
| 210 wm::WmWindow* magnetism_window_; | |
| 211 | |
| 212 // Used to verify |magnetism_window_| is still valid. | |
| 213 wm::WmWindowTracker window_tracker_; | |
| 214 | |
| 215 // If |magnetism_window_| is non-NULL this indicates how the two windows | |
| 216 // should attach. | |
| 217 MatchedEdge magnetism_edge_; | |
| 218 | |
| 219 // Dock container window layout manager. | |
| 220 DockedWindowLayoutManager* dock_layout_; | |
| 221 | |
| 222 // Used to determine if this has been deleted during a drag such as when a tab | |
| 223 // gets dragged into another browser window. | |
| 224 base::WeakPtrFactory<WorkspaceWindowResizer> weak_ptr_factory_; | |
| 225 | |
| 226 DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizer); | |
| 227 }; | |
| 228 | |
| 229 } // namespace ash | |
| 230 | |
| 231 #endif // ASH_WM_WORKSPACE_WORKSPACE_WINDOW_RESIZER_H_ | |
| OLD | NEW |