view_model_utils.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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 "ui/views/view_model_utils.h"
6
7#include <algorithm>
8
9#include "ui/views/view.h"
10#include "ui/views/view_model.h"
11
12namespace views {
13
14namespace {
15
16// Used in calculating ideal bounds.
17int primary_axis_coordinate(ViewModelUtils::Alignment alignment,
18                            int x,
19                            int y) {
20  return alignment == ViewModelUtils::HORIZONTAL ? x : y;
21}
22
23}  // namespace
24
25// static
26void ViewModelUtils::SetViewBoundsToIdealBounds(const ViewModel& model) {
27  for (int i = 0; i < model.view_size(); ++i)
28    model.view_at(i)->SetBoundsRect(model.ideal_bounds(i));
29}
30
31// static
32bool ViewModelUtils::IsAtIdealBounds(const ViewModel& model) {
33  for (int i = 0; i < model.view_size(); ++i) {
34    View* view = model.view_at(i);
35    if (view->bounds() != model.ideal_bounds(i))
36      return false;
37  }
38  return true;
39}
40
41// static
42int ViewModelUtils::DetermineMoveIndex(const ViewModel& model,
43                                       View* view,
44                                       Alignment alignment,
45                                       int x,
46                                       int y) {
47  int value = primary_axis_coordinate(alignment, x, y);
48  int current_index = model.GetIndexOfView(view);
49  DCHECK_NE(-1, current_index);
50  for (int i = 0; i < current_index; ++i) {
51    int mid_point = primary_axis_coordinate(
52        alignment,
53        model.ideal_bounds(i).x() + model.ideal_bounds(i).width() / 2,
54        model.ideal_bounds(i).y() + model.ideal_bounds(i).height() / 2);
55    if (value < mid_point)
56      return i;
57  }
58
59  if (current_index + 1 == model.view_size())
60    return current_index;
61
62  // For indices after the current index ignore the bounds of the view being
63  // dragged. This keeps the view from bouncing around as moved.
64  int delta = primary_axis_coordinate(
65      alignment,
66      model.ideal_bounds(current_index + 1).x() -
67      model.ideal_bounds(current_index).x(),
68      model.ideal_bounds(current_index + 1).y() -
69      model.ideal_bounds(current_index).y());
70  for (int i = current_index + 1; i < model.view_size(); ++i) {
71    const gfx::Rect& bounds(model.ideal_bounds(i));
72    int mid_point = primary_axis_coordinate(
73        alignment,
74        bounds.x() + bounds.width() / 2 - delta,
75        bounds.y() + bounds.height() / 2 - delta);
76    if (value < mid_point)
77      return i - 1;
78  }
79  return model.view_size() - 1;
80}
81
82}  // namespace views
83