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)#ifndef CHROME_BROWSER_UI_PANELS_PANEL_DRAG_CONTROLLER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_UI_PANELS_PANEL_DRAG_CONTROLLER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/panel_collection.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/vector2d.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Panel;
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PanelCollection;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PanelManager;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Point;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Rect;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Controls all the drags initiated for all panels, including detaching,
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// docking, stacking, snapping and intra-collection dragging.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PanelDragController {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit PanelDragController(PanelManager* panel_manager);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~PanelDragController();
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Drags the given panel.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |mouse_location| is in screen coordinate system.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartDragging(Panel* panel, const gfx::Point& mouse_location);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Drag(const gfx::Point& mouse_location);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EndDragging(bool cancelled);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Asynchronous confirmation of panel having been closed.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnPanelClosed(Panel* panel);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_dragging() const { return dragging_panel_ != NULL; }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Panel* dragging_panel() const { return dragging_panel_; }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For testing.
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static int GetDetachDockedPanelThresholdForTesting();
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static int GetDockDetachedPanelThresholdForTesting();
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static int GetGluePanelDistanceThresholdForTesting();
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static int GetGluePanelOverlapThresholdForTesting();
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static int GetSnapPanelToScreenEdgeThresholdForTesting();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum GlueAction {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    STACK,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SNAP
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum GlueEdge {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TOP_EDGE,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BOTTOM_EDGE,
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LEFT_EDGE,
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RIGHT_EDGE
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point GetPanelPositionForMouseLocation(
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const gfx::Point& mouse_location) const;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |target_position| is in screen coordinate systems. It contains the proposed
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //  panel origin to move to. Returns true if the request has been performed.
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void TryDetach(const gfx::Point& target_position);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void TryDock(const gfx::Point& target_position);
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void TryStack(const gfx::Point& target_position);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool TryUnstackFromTop(const gfx::Point& target_position);
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool TryUnstackFromBottom(const gfx::Point& target_position);
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void TrySnap(gfx::Point* target_position);
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Finds the panel that the dragging panel with |potential_position| could
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // snap to or stack with. If such panel is found, |target_bounds| contains the
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // new bounds for the dragging panel and |target_edge| contains the matched
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // edge.
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Panel* FindPanelToGlue(const gfx::Point& potential_position,
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         GlueAction action,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         gfx::Rect* target_bounds,
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         GlueEdge* target_edge) const;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Moves the |panel| (and all panels below if it is in a stack) to a different
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // collection.
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void MovePanelAndBelowToCollection(
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Panel* panel,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PanelCollection* target_collection,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PanelCollection::PositioningMask positioning_mask) const;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PanelManager* panel_manager_;  // Weak, owns us.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool panel_stacking_enabled_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Panel currently being dragged.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Panel* dragging_panel_;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The original panel collection when the drag is started.
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PanelCollection* dragging_panel_original_collection_;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The offset from mouse location to the panel position when the drag
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // starts.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Vector2d offset_from_mouse_location_on_drag_start_;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PanelDragController);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_UI_PANELS_PANEL_DRAG_CONTROLLER_H_
104