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#ifndef CHROME_BROWSER_UI_PANELS_PANEL_DRAG_CONTROLLER_H_
6#define CHROME_BROWSER_UI_PANELS_PANEL_DRAG_CONTROLLER_H_
7
8#include "base/memory/scoped_ptr.h"
9#include "chrome/browser/ui/panels/panel_collection.h"
10#include "ui/gfx/vector2d.h"
11
12class Panel;
13class PanelCollection;
14class PanelManager;
15namespace gfx {
16class Point;
17class Rect;
18}
19
20// Controls all the drags initiated for all panels, including detaching,
21// docking, stacking, snapping and intra-collection dragging.
22class PanelDragController {
23 public:
24  explicit PanelDragController(PanelManager* panel_manager);
25  ~PanelDragController();
26
27  // Drags the given panel.
28  // |mouse_location| is in screen coordinate system.
29  void StartDragging(Panel* panel, const gfx::Point& mouse_location);
30  void Drag(const gfx::Point& mouse_location);
31  void EndDragging(bool cancelled);
32
33  // Asynchronous confirmation of panel having been closed.
34  void OnPanelClosed(Panel* panel);
35
36  bool is_dragging() const { return dragging_panel_ != NULL; }
37  Panel* dragging_panel() const { return dragging_panel_; }
38
39  // For testing.
40  static int GetDetachDockedPanelThresholdForTesting();
41  static int GetDockDetachedPanelThresholdForTesting();
42  static int GetGluePanelDistanceThresholdForTesting();
43  static int GetGluePanelOverlapThresholdForTesting();
44  static int GetSnapPanelToScreenEdgeThresholdForTesting();
45
46 private:
47  enum GlueAction {
48    STACK,
49    SNAP
50  };
51
52  enum GlueEdge {
53    TOP_EDGE,
54    BOTTOM_EDGE,
55    LEFT_EDGE,
56    RIGHT_EDGE
57  };
58
59  gfx::Point GetPanelPositionForMouseLocation(
60      const gfx::Point& mouse_location) const;
61
62  // |target_position| is in screen coordinate systems. It contains the proposed
63  //  panel origin to move to. Returns true if the request has been performed.
64  void TryDetach(const gfx::Point& target_position);
65  void TryDock(const gfx::Point& target_position);
66  void TryStack(const gfx::Point& target_position);
67  bool TryUnstackFromTop(const gfx::Point& target_position);
68  bool TryUnstackFromBottom(const gfx::Point& target_position);
69  void TrySnap(gfx::Point* target_position);
70
71  // Finds the panel that the dragging panel with |potential_position| could
72  // snap to or stack with. If such panel is found, |target_bounds| contains the
73  // new bounds for the dragging panel and |target_edge| contains the matched
74  // edge.
75  Panel* FindPanelToGlue(const gfx::Point& potential_position,
76                         GlueAction action,
77                         gfx::Rect* target_bounds,
78                         GlueEdge* target_edge) const;
79
80  // Moves the |panel| (and all panels below if it is in a stack) to a different
81  // collection.
82  void MovePanelAndBelowToCollection(
83      Panel* panel,
84      PanelCollection* target_collection,
85      PanelCollection::PositioningMask positioning_mask) const;
86
87  PanelManager* panel_manager_;  // Weak, owns us.
88  bool panel_stacking_enabled_;
89
90  // Panel currently being dragged.
91  Panel* dragging_panel_;
92
93  // The original panel collection when the drag is started.
94  PanelCollection* dragging_panel_original_collection_;
95
96  // The offset from mouse location to the panel position when the drag
97  // starts.
98  gfx::Vector2d offset_from_mouse_location_on_drag_start_;
99
100  DISALLOW_COPY_AND_ASSIGN(PanelDragController);
101};
102
103#endif  // CHROME_BROWSER_UI_PANELS_PANEL_DRAG_CONTROLLER_H_
104