| Index: chrome/browser/ui/panels/panel_drag_controller.cc
|
| diff --git a/chrome/browser/ui/panels/panel_drag_controller.cc b/chrome/browser/ui/panels/panel_drag_controller.cc
|
| index 7cd099053250f7f231d2d5a9c357245f66f0f825..fd0aee9ddf72f147cc83cc2c3015c54afb39bcc0 100644
|
| --- a/chrome/browser/ui/panels/panel_drag_controller.cc
|
| +++ b/chrome/browser/ui/panels/panel_drag_controller.cc
|
| @@ -5,11 +5,20 @@
|
| #include "chrome/browser/ui/panels/panel_drag_controller.h"
|
|
|
| #include "base/logging.h"
|
| +#include "chrome/browser/ui/panels/detached_panel_strip.h"
|
| +#include "chrome/browser/ui/panels/docked_panel_strip.h"
|
| #include "chrome/browser/ui/panels/panel.h"
|
| +#include "chrome/browser/ui/panels/panel_manager.h"
|
| #include "chrome/browser/ui/panels/panel_strip.h"
|
|
|
| -PanelDragController::PanelDragController()
|
| - : dragging_panel_(NULL) {
|
| +// static
|
| +const int PanelDragController::kDetachDockedPanelThreshold = 80;
|
| +const int PanelDragController::kDockDetachedPanelThreshold = 10;
|
| +
|
| +PanelDragController::PanelDragController(PanelManager* panel_manager)
|
| + : panel_manager_(panel_manager),
|
| + dragging_panel_(NULL),
|
| + dragging_panel_original_strip_(NULL) {
|
| }
|
|
|
| PanelDragController::~PanelDragController() {
|
| @@ -23,18 +32,54 @@ void PanelDragController::StartDragging(Panel* panel,
|
| last_mouse_location_ = mouse_location;
|
|
|
| dragging_panel_ = panel;
|
| - dragging_panel_original_position_ = panel->GetBounds().origin();
|
| + dragging_panel_->SetPreviewMode(true);
|
| +
|
| + // Keep track of original strip and placement for the case that the drag is
|
| + // cancelled.
|
| + dragging_panel_original_strip_ = dragging_panel_->panel_strip();
|
| + dragging_panel_original_strip_->SavePanelPlacement(dragging_panel_);
|
|
|
| - dragging_panel_->panel_strip()->StartDraggingPanel(panel);
|
| + if (dragging_panel_original_strip_->type() == PanelStrip::DOCKED)
|
| + mouse_location_on_docked_ = last_mouse_location_;
|
| + dragging_panel_original_strip_->StartDraggingPanelWithinStrip(
|
| + dragging_panel_);
|
| }
|
|
|
| void PanelDragController::Drag(const gfx::Point& mouse_location) {
|
| DCHECK(dragging_panel_);
|
|
|
| - dragging_panel_->panel_strip()->DragPanel(
|
| + PanelStrip* current_strip = dragging_panel_->panel_strip();
|
| +
|
| + // We also need to compute target panel position together with target strip.
|
| + // This is because target panel position needs to be computed in special way
|
| + // when drag leaves docked strip and enters detached strip (see comment in
|
| + // CanDragToDetachedStrip).
|
| + gfx::Point target_panel_position;
|
| + PanelStrip* target_strip = ComputeDragTagetStrip(
|
| + mouse_location, &target_panel_position);
|
| + if (target_strip != current_strip) {
|
| + // End the dragging in old strip.
|
| + current_strip->EndDraggingPanelWithinStrip(dragging_panel_, true);
|
| +
|
| + // Apply new panel position.
|
| + gfx::Rect new_bounds(dragging_panel_->GetBounds());
|
| + new_bounds.set_origin(target_panel_position);
|
| + dragging_panel_->SetPanelBounds(new_bounds);
|
| +
|
| + // Move the panel to new strip.
|
| + panel_manager_->MovePanelToStrip(dragging_panel_, target_strip->type());
|
| +
|
| + if (target_strip->type() == PanelStrip::DOCKED)
|
| + mouse_location_on_docked_ = mouse_location;
|
| +
|
| + // Start the dragging in new strip.
|
| + target_strip->StartDraggingPanelWithinStrip(dragging_panel_);
|
| + } else {
|
| + current_strip->DragPanelWithinStrip(
|
| dragging_panel_,
|
| mouse_location.x() - last_mouse_location_.x(),
|
| mouse_location.y() - last_mouse_location_.y());
|
| + }
|
|
|
| last_mouse_location_ = mouse_location;
|
| }
|
| @@ -42,12 +87,100 @@ void PanelDragController::Drag(const gfx::Point& mouse_location) {
|
| void PanelDragController::EndDragging(bool cancelled) {
|
| DCHECK(dragging_panel_);
|
|
|
| - // The code in PanelStrip::EndDraggingPanel might call DragController to find
|
| - // out if the drag has ended. So we need to reset |dragging_panel_| to reflect
|
| - // this.
|
| - Panel* panel = dragging_panel_;
|
| + PanelStrip* current_strip = dragging_panel_->panel_strip();
|
| + if (cancelled) {
|
| + // Abort the drag in current strip.
|
| + current_strip->EndDraggingPanelWithinStrip(dragging_panel_, true);
|
| +
|
| + // Restore the dragging panel to its original strip if needed.
|
| + if (current_strip != dragging_panel_original_strip_) {
|
| + panel_manager_->MovePanelToStrip(
|
| + dragging_panel_, dragging_panel_original_strip_->type());
|
| + }
|
| +
|
| + // We need to clear the preview mode before restoring to the saved placement
|
| + // because otherwise the panel will remain as it is.
|
| + dragging_panel_->SetPreviewMode(false);
|
| +
|
| + // Restore the dragging panel to its original placement.
|
| + dragging_panel_original_strip_->RestorePanelToSavedPlacement();
|
| + } else {
|
| + // We need to clear the preview mode first because in this mode, the panel
|
| + // will remain as it is.
|
| + dragging_panel_->SetPreviewMode(false);
|
| +
|
| + // End the drag. This will cause the panel to be moved to its finalized
|
| + // position.
|
| + current_strip->EndDraggingPanelWithinStrip(dragging_panel_, false);
|
| +
|
| + // The saved placement is not needed when the drag ends.
|
| + dragging_panel_original_strip_->DiscardSavedPanelPlacement();
|
| + }
|
| +
|
| dragging_panel_ = NULL;
|
| - panel->panel_strip()->EndDraggingPanel(panel, cancelled);
|
| +}
|
| +
|
| +PanelStrip* PanelDragController::ComputeDragTagetStrip(
|
| + const gfx::Point& mouse_location, gfx::Point* new_panel_position) const {
|
| + if (CanDragToDockedStrip(mouse_location, new_panel_position))
|
| + return panel_manager_->docked_strip();
|
| + else if (CanDragToDetachedStrip(mouse_location, new_panel_position))
|
| + return panel_manager_->detached_strip();
|
| + else
|
| + return dragging_panel_->panel_strip();
|
| +}
|
| +
|
| +bool PanelDragController::CanDragToDockedStrip(
|
| + const gfx::Point& mouse_location,
|
| + gfx::Point* new_panel_position) const {
|
| + // It has to come from the detached strip.
|
| + if (dragging_panel_->panel_strip()->type() != PanelStrip::DETACHED)
|
| + return false;
|
| +
|
| + // The bottom of the panel should come very close to or fall below the bottom
|
| + // of the docked area.
|
| + int new_panel_bottom = dragging_panel_->GetBounds().bottom() +
|
| + mouse_location.y() - last_mouse_location_.y();
|
| + int docked_area_bottom =
|
| + panel_manager_->docked_strip()->display_area().bottom();
|
| + if (docked_area_bottom - new_panel_bottom > kDockDetachedPanelThreshold)
|
| + return false;
|
| +
|
| + *new_panel_position = dragging_panel_->GetBounds().origin();
|
| + new_panel_position->Offset(
|
| + mouse_location.x() - last_mouse_location_.x(),
|
| + mouse_location.y() - last_mouse_location_.y());
|
| + return true;
|
| +}
|
| +
|
| +bool PanelDragController::CanDragToDetachedStrip(
|
| + const gfx::Point& mouse_location,
|
| + gfx::Point* new_panel_position) const {
|
| + // It has to come from the docked strip.
|
| + if (dragging_panel_->panel_strip()->type() != PanelStrip::DOCKED)
|
| + return false;
|
| +
|
| + // The minimized docked panel is not allowed to detach.
|
| + if (dragging_panel_->expansion_state() != Panel::EXPANDED)
|
| + return false;
|
| +
|
| + // The panel should be dragged up high enough to pass certain threshold.
|
| + if (mouse_location.y() >= mouse_location_on_docked_.y() ||
|
| + mouse_location_on_docked_.y() - mouse_location.y() <
|
| + kDetachDockedPanelThreshold)
|
| + return false;
|
| +
|
| + // When the mouse drags within the docked strip, we only update panel's x
|
| + // coordinate while keep its y coordinate unchanged. When the panel is
|
| + // detached, the panel should jump immediately to follow the mouse location.
|
| + // That is, its new y coordinate should be computed based on the distance
|
| + // between current mouse location and the mouse location when the drag starts
|
| + // within the docked strip.
|
| + *new_panel_position = dragging_panel_->GetBounds().origin();
|
| + new_panel_position->Offset(
|
| + mouse_location.x() - last_mouse_location_.x(),
|
| + mouse_location.y() - mouse_location_on_docked_.y());
|
| + return true;
|
| }
|
|
|
| void PanelDragController::OnPanelClosed(Panel* panel) {
|
|
|