15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/workspace/snap_sizer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cmath>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/screen_ash.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/property_util.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_resizer.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/window_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A list of ideal window width in pixel which will be used to populate the
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |usable_width_| list.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kIdealWidth[] = { 1280, 1024, 768, 640 };
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows are initially snapped to the size in |usable_width_| at index 0.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The index into |usable_width_| is changed if any of the following happen:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// . The user stops moving the mouse for |kDelayBeforeIncreaseMS| and then
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   moves the mouse again.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// . The mouse moves |kPixelsBeforeAdjust| horizontal pixels.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// . The mouse is against the edge of the screen and the mouse is moved
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   |kMovesBeforeAdjust| times.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDelayBeforeIncreaseMS = 500;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMovesBeforeAdjust = 25;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kPixelsBeforeAdjust = 100;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When the smallest resolution does not fit on the screen, we take this
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fraction of the available space.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinimumScreenPercent = 90;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Create the list of possible width for the current screen configuration:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fill the |usable_width_| list with items from |kIdealWidth| which fit on
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the screen and supplement it with the 'half of screen' size. Furthermore,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// add an entry for 90% of the screen size if it is smaller then the biggest
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// value in the |kIdealWidth| list (to get a step between the values).
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<int> BuildIdealWidthList(aura::Window* window) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int> ideal_width_list;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int half_size = work_area.width() / 2;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int maximum_width = (kMinimumScreenPercent * work_area.width()) / 100;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kIdealWidth); i++) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (maximum_width >= kIdealWidth[i]) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (i && !ideal_width_list.size() && maximum_width != kIdealWidth[i])
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ideal_width_list.push_back(maximum_width);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (half_size > kIdealWidth[i])
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ideal_width_list.push_back(half_size);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (half_size >= kIdealWidth[i])
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        half_size = 0;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ideal_width_list.push_back(kIdealWidth[i]);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (half_size)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ideal_width_list.push_back(half_size);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ideal_width_list;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SnapSizer::SnapSizer(aura::Window* window,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const gfx::Point& start,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     Edge edge,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     InputType input_type)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : window_(window),
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      edge_(edge),
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      time_last_update_(base::TimeTicks::Now()),
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_index_(0),
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      resize_disabled_(false),
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_moves_since_adjust_(0),
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_adjust_x_(start.x()),
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_update_x_(start.x()),
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      start_x_(start.x()),
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      input_type_(input_type),
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      usable_width_(BuildIdealWidthList(window)) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!usable_width_.empty());
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_bounds_ = GetTargetBounds();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SnapSizer::~SnapSizer() {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SnapSizer::SnapWindow(aura::Window* window, SnapSizer::Edge edge) {
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!wm::CanSnapWindow(window))
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  internal::SnapSizer sizer(window, gfx::Point(), edge,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal::SnapSizer::OTHER_INPUT);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (wm::IsWindowFullscreen(window) || wm::IsWindowMaximized(window)) {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Before we can set the bounds we need to restore the window.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Restoring the window will set the window to its restored bounds.
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // To avoid an unnecessary bounds changes (which may have side effects)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // we set the restore bounds to the bounds we want, restore the window,
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // then reset the restore bounds. This way no unnecessary bounds
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // changes occurs and the original restore bounds is remembered.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect restore = *GetRestoreBoundsInScreen(window);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetRestoreBoundsInParent(window, sizer.GetSnapBounds(window->bounds()));
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    wm::RestoreWindow(window);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetRestoreBoundsInScreen(window, restore);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window->SetBounds(sizer.GetSnapBounds(window->bounds()));
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SnapSizer::Update(const gfx::Point& location) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See description above for details on this behavior.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  num_moves_since_adjust_++;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((base::TimeTicks::Now() - time_last_update_).InMilliseconds() >
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kDelayBeforeIncreaseMS) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChangeBounds(location.x(),
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 CalculateIncrement(location.x(), last_update_x_));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool along_edge = AlongEdge(location.x());
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int pixels_before_adjust = kPixelsBeforeAdjust;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (input_type_ == TOUCH_MAXIMIZE_BUTTON_INPUT) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const gfx::Rect& workspace_bounds = window_->parent()->bounds();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (start_x_ > location.x()) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pixels_before_adjust =
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            std::min(pixels_before_adjust, start_x_ / 10);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pixels_before_adjust =
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            std::min(pixels_before_adjust,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     (workspace_bounds.width() - start_x_) / 10);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (std::abs(location.x() - last_adjust_x_) >= pixels_before_adjust ||
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (along_edge && num_moves_since_adjust_ >= kMovesBeforeAdjust)) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChangeBounds(location.x(),
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   CalculateIncrement(location.x(), last_adjust_x_));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_update_x_ = location.x();
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  time_last_update_ = base::TimeTicks::Now();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect SnapSizer::GetSnapBounds(const gfx::Rect& bounds) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int current = 0;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!resize_disabled_) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (current = usable_width_.size() - 1; current >= 0; current--) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Rect target = GetTargetBoundsForSize(current);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (target == bounds) {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++current;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetTargetBoundsForSize(current % usable_width_.size());
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SnapSizer::SelectDefaultSizeAndDisableResize() {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resize_disabled_ = true;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_index_ = 0;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_bounds_ = GetTargetBounds();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect SnapSizer::GetTargetBoundsForSize(size_t size_index) const {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int y = work_area.y();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't align to the bottom of the grid as the launcher may not
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // necessarily align to the grid (happens when auto-hidden).
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_y = work_area.bottom();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int width = 0;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (resize_disabled_) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure that we keep the size of the window smaller then a certain
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // fraction of the screen space.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int minimum_size = (kMinimumScreenPercent * work_area.width()) / 100;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    width = std::max(std::min(minimum_size, 1024), work_area.width() / 2);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(size_index < usable_width_.size());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    width = usable_width_[size_index];
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (edge_ == LEFT_EDGE) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int x = work_area.x();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mid_x = x + width;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gfx::Rect(x, y, mid_x - x, max_y - y);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_x = work_area.right();
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int x = max_x - width;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Rect(x , y, max_x - x, max_y - y);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SnapSizer::CalculateIncrement(int x, int reference_x) const {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (AlongEdge(x))
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 1;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (x == reference_x)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (edge_ == LEFT_EDGE) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (x < reference_x)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 1;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // edge_ == RIGHT_EDGE.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (x > reference_x)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 1;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return -1;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SnapSizer::ChangeBounds(int x, int delta) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int index = std::min(static_cast<int>(usable_width_.size()) - 1,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       std::max(size_index_ + delta, 0));
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (index != size_index_) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_index_ = index;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    target_bounds_ = GetTargetBounds();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  num_moves_since_adjust_ = 0;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_adjust_x_ = x;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect SnapSizer::GetTargetBounds() const {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetTargetBoundsForSize(size_index_);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SnapSizer::AlongEdge(int x) const {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect area(ScreenAsh::GetDisplayBoundsInParent(window_));
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (x <= area.x()) || (x >= area.right() - 1);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
228