12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/stacked_panel_drag_handler.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/panel.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/panel_collection.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/stacked_panel_collection.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/point.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelDragHandler::HandleDrag(Panel* panel,
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         const gfx::Point& target_position,
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         bool in_orginal_collection) {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(PanelCollection::STACKED, panel->collection()->type());
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StackedPanelCollection* stack = panel->stack();
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(stack);
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the panel is in its original stack, only top panel is allowed to drag.
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (in_orginal_collection && panel != stack->top_panel())
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Find out if all panels in the stack are being dragged.
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool all_panels_under_drag = true;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (StackedPanelCollection::Panels::const_iterator iter =
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           stack->panels().begin();
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != stack->panels().end(); ++iter) {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!(*iter)->in_preview_mode()) {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      all_panels_under_drag = false;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2d delta_origin = target_position - panel->GetBounds().origin();
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If not all panels in the stack are being dragged, it means that these
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // panels being dragged have just been added to this stack. Dragging these
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // panels should only cause the horizontal movement due to that y position
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // of these panels have already aligned.
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!all_panels_under_drag)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delta_origin.set_y(0);
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stack->MoveAllDraggingPanelsInstantly(delta_origin);
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelDragHandler::FinalizeDrag(Panel* panel) {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(PanelCollection::STACKED, panel->collection()->type());
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StackedPanelCollection* stack = panel->stack();
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(stack);
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // It is only needed when dragging a panel/stack to stack to the top of
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // another panel/stack.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (stack->top_panel() != panel)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Find the first non-dragging panel that is used to align all dragging panels
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // above it to have the same x position. This is because all dragging panels
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // are only aligned vertically when the stacking occurs.
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Panel* first_non_dragging_panel = NULL;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (StackedPanelCollection::Panels::const_iterator iter =
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           stack->panels().begin();
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != stack->panels().end(); ++iter) {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Panel* panel = *iter;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!panel->in_preview_mode()) {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_non_dragging_panel = panel;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!first_non_dragging_panel)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2d delta_origin(
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_non_dragging_panel->GetBounds().x() - panel->GetBounds().x(),
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stack->MoveAllDraggingPanelsInstantly(delta_origin);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
83