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 "ui/views/view_model_utils.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view_model.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used in calculating ideal bounds.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int primary_axis_coordinate(ViewModelUtils::Alignment alignment,
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            int x,
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            int y) {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return alignment == ViewModelUtils::HORIZONTAL ? x : y;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewModelUtils::SetViewBoundsToIdealBounds(const ViewModel& model) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < model.view_size(); ++i)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model.view_at(i)->SetBoundsRect(model.ideal_bounds(i));
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ViewModelUtils::IsAtIdealBounds(const ViewModel& model) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < model.view_size(); ++i) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    View* view = model.view_at(i);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (view->bounds() != model.ideal_bounds(i))
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewModelUtils::DetermineMoveIndex(const ViewModel& model,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       View* view,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       Alignment alignment,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       int x,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       int y) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int value = primary_axis_coordinate(alignment, x, y);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int current_index = model.GetIndexOfView(view);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(-1, current_index);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < current_index; ++i) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mid_point = primary_axis_coordinate(
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        alignment,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        model.ideal_bounds(i).x() + model.ideal_bounds(i).width() / 2,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        model.ideal_bounds(i).y() + model.ideal_bounds(i).height() / 2);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value < mid_point)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return i;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (current_index + 1 == model.view_size())
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return current_index;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For indices after the current index ignore the bounds of the view being
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // dragged. This keeps the view from bouncing around as moved.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int delta = primary_axis_coordinate(
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      alignment,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model.ideal_bounds(current_index + 1).x() -
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model.ideal_bounds(current_index).x(),
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model.ideal_bounds(current_index + 1).y() -
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model.ideal_bounds(current_index).y());
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = current_index + 1; i < model.view_size(); ++i) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& bounds(model.ideal_bounds(i));
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mid_point = primary_axis_coordinate(
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        alignment,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bounds.x() + bounds.width() / 2 - delta,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bounds.y() + bounds.height() / 2 - delta);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (value < mid_point)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return i - 1;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return model.view_size() - 1;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
83