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 #include "ash/wm/workspace/snap_sizer.h" |
| 6 |
| 7 #include <cmath> |
| 8 |
| 9 #include "ash/wm/window_resizer.h" |
| 10 #include "ui/aura/window.h" |
| 11 #include "ui/gfx/screen.h" |
| 12 |
| 13 namespace ash { |
| 14 namespace internal { |
| 15 |
| 16 namespace { |
| 17 |
| 18 // Percent of the screen (width) to give the window. |
| 19 const float kPercents[] = { .5f, 2.0f / 3.0f, .8f }; |
| 20 |
| 21 // Windows are initially snapped to the percent at index 0. The index into |
| 22 // |kPercents| is changed if any of the following happen: |
| 23 // . The user stops moving the mouse for |kDelayBeforeIncreaseMS| and then moves |
| 24 // the mouse again. |
| 25 // . The mouse moves |kPixelsBeforeAdjust| horizontal pixels. |
| 26 // . The mouse is against the edge of the screen and the mouse is moved |
| 27 // |kMovesBeforeAdjust| times. |
| 28 const int kDelayBeforeIncreaseMS = 500; |
| 29 const int kMovesBeforeAdjust = 50; |
| 30 const int kPixelsBeforeAdjust = 200; |
| 31 |
| 32 } // namespace |
| 33 |
| 34 SnapSizer::SnapSizer(aura::Window* window, |
| 35 const gfx::Point& start, |
| 36 Edge edge, |
| 37 int grid_size) |
| 38 : window_(window), |
| 39 edge_(edge), |
| 40 grid_size_(grid_size), |
| 41 time_last_update_(base::TimeTicks::Now()), |
| 42 percent_index_(0), |
| 43 num_moves_since_adjust_(0), |
| 44 last_adjust_x_(start.x()), |
| 45 last_update_x_(start.x()) { |
| 46 target_bounds_ = GetTargetBounds(); |
| 47 } |
| 48 |
| 49 void SnapSizer::Update(const gfx::Point& location) { |
| 50 // See description above for details on this behavior. |
| 51 num_moves_since_adjust_++; |
| 52 if ((base::TimeTicks::Now() - time_last_update_).InMilliseconds() > |
| 53 kDelayBeforeIncreaseMS) { |
| 54 ChangeBounds(location.x(), |
| 55 CalculateIncrement(location.x(), last_update_x_)); |
| 56 } else { |
| 57 bool along_edge = AlongEdge(location.x()); |
| 58 if (std::abs(location.x() - last_adjust_x_) >= kPixelsBeforeAdjust || |
| 59 (along_edge && num_moves_since_adjust_ >= kMovesBeforeAdjust)) { |
| 60 ChangeBounds(location.x(), |
| 61 CalculateIncrement(location.x(), last_adjust_x_)); |
| 62 } |
| 63 } |
| 64 last_update_x_ = location.x(); |
| 65 time_last_update_ = base::TimeTicks::Now(); |
| 66 } |
| 67 |
| 68 int SnapSizer::CalculateIncrement(int x, int reference_x) const { |
| 69 if (AlongEdge(x)) |
| 70 return 1; |
| 71 if (x == reference_x) |
| 72 return 0; |
| 73 if (edge_ == LEFT_EDGE) { |
| 74 if (x < reference_x) |
| 75 return 1; |
| 76 return -1; |
| 77 } |
| 78 // edge_ == RIGHT_EDGE. |
| 79 if (x > reference_x) |
| 80 return 1; |
| 81 return -1; |
| 82 } |
| 83 |
| 84 void SnapSizer::ChangeBounds(int x, int delta) { |
| 85 int index = std::min(static_cast<int>(arraysize(kPercents)) - 1, |
| 86 std::max(percent_index_ + delta, 0)); |
| 87 if (index != percent_index_) { |
| 88 percent_index_ = index; |
| 89 target_bounds_ = GetTargetBounds(); |
| 90 } |
| 91 num_moves_since_adjust_ = 0; |
| 92 last_adjust_x_ = x; |
| 93 } |
| 94 |
| 95 gfx::Rect SnapSizer::GetTargetBounds() const { |
| 96 gfx::Rect work_area(gfx::Screen::GetMonitorWorkAreaNearestWindow(window_)); |
| 97 int y = WindowResizer::AlignToGridRoundUp(work_area.y(), grid_size_); |
| 98 int max_y = |
| 99 WindowResizer::AlignToGridRoundDown(work_area.bottom(), grid_size_); |
| 100 int width = static_cast<float>(work_area.width()) * kPercents[percent_index_]; |
| 101 if (edge_ == LEFT_EDGE) { |
| 102 int x = WindowResizer::AlignToGridRoundUp(work_area.x(), grid_size_); |
| 103 int mid_x = WindowResizer::AlignToGridRoundUp( |
| 104 work_area.x() + width, grid_size_); |
| 105 return gfx::Rect(x, y, mid_x - x, max_y - y); |
| 106 } |
| 107 int max_x = |
| 108 WindowResizer::AlignToGridRoundDown(work_area.right(), grid_size_); |
| 109 int x = WindowResizer::AlignToGridRoundUp(max_x - width, grid_size_); |
| 110 return gfx::Rect(x , y, max_x - x, max_y - y); |
| 111 } |
| 112 |
| 113 bool SnapSizer::AlongEdge(int x) const { |
| 114 // TODO: need to support multi-monitor. |
| 115 gfx::Rect area(gfx::Screen::GetMonitorAreaNearestWindow(window_)); |
| 116 return (x <= area.x()) || (x >= area.right() - 1); |
| 117 } |
| 118 |
| 119 } // namespace internal |
| 120 } // namespace ash |
OLD | NEW |