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 "chrome/browser/ui/panels/stacked_panel_drag_handler.h"
6
7#include "base/logging.h"
8#include "chrome/browser/ui/panels/panel.h"
9#include "chrome/browser/ui/panels/panel_collection.h"
10#include "chrome/browser/ui/panels/stacked_panel_collection.h"
11#include "ui/gfx/point.h"
12#include "ui/gfx/rect.h"
13
14// static
15void StackedPanelDragHandler::HandleDrag(Panel* panel,
16                                         const gfx::Point& target_position,
17                                         bool in_orginal_collection) {
18  DCHECK_EQ(PanelCollection::STACKED, panel->collection()->type());
19
20  StackedPanelCollection* stack = panel->stack();
21  DCHECK(stack);
22
23  // If the panel is in its original stack, only top panel is allowed to drag.
24  if (in_orginal_collection && panel != stack->top_panel())
25    return;
26
27  // Find out if all panels in the stack are being dragged.
28  bool all_panels_under_drag = true;
29  for (StackedPanelCollection::Panels::const_iterator iter =
30           stack->panels().begin();
31       iter != stack->panels().end(); ++iter) {
32    if (!(*iter)->in_preview_mode()) {
33      all_panels_under_drag = false;
34      break;
35    }
36  }
37
38  gfx::Vector2d delta_origin = target_position - panel->GetBounds().origin();
39
40  // If not all panels in the stack are being dragged, it means that these
41  // panels being dragged have just been added to this stack. Dragging these
42  // panels should only cause the horizontal movement due to that y position
43  // of these panels have already aligned.
44  if (!all_panels_under_drag)
45    delta_origin.set_y(0);
46
47  stack->MoveAllDraggingPanelsInstantly(delta_origin);
48}
49
50// static
51void StackedPanelDragHandler::FinalizeDrag(Panel* panel) {
52  DCHECK_EQ(PanelCollection::STACKED, panel->collection()->type());
53
54  StackedPanelCollection* stack = panel->stack();
55  DCHECK(stack);
56
57  // It is only needed when dragging a panel/stack to stack to the top of
58  // another panel/stack.
59  if (stack->top_panel() != panel)
60    return;
61
62  // Find the first non-dragging panel that is used to align all dragging panels
63  // above it to have the same x position. This is because all dragging panels
64  // are only aligned vertically when the stacking occurs.
65  Panel* first_non_dragging_panel = NULL;
66  for (StackedPanelCollection::Panels::const_iterator iter =
67           stack->panels().begin();
68       iter != stack->panels().end(); ++iter) {
69    Panel* panel = *iter;
70    if (!panel->in_preview_mode()) {
71      first_non_dragging_panel = panel;
72      break;
73    }
74  }
75  if (!first_non_dragging_panel)
76    return;
77
78  gfx::Vector2d delta_origin(
79      first_non_dragging_panel->GetBounds().x() - panel->GetBounds().x(),
80      0);
81  stack->MoveAllDraggingPanelsInstantly(delta_origin);
82}
83