Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/panels/panel_drag_controller.h" | 5 #include "chrome/browser/ui/panels/panel_drag_controller.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "chrome/browser/ui/panels/detached_panel_strip.h" | |
| 9 #include "chrome/browser/ui/panels/docked_panel_strip.h" | |
| 8 #include "chrome/browser/ui/panels/panel.h" | 10 #include "chrome/browser/ui/panels/panel.h" |
| 11 #include "chrome/browser/ui/panels/panel_manager.h" | |
| 9 #include "chrome/browser/ui/panels/panel_strip.h" | 12 #include "chrome/browser/ui/panels/panel_strip.h" |
| 13 #include "ui/gfx/rect.h" | |
| 10 | 14 |
| 11 PanelDragController::PanelDragController() | 15 // static |
| 12 : dragging_panel_(NULL) { | 16 const int PanelDragController::kDetachDockedPanelThreshold = 60; |
| 17 const int PanelDragController::kDockDetachedPanelThreshold = 30; | |
| 18 | |
| 19 PanelDragController::PanelDragController(PanelManager* panel_manager) | |
| 20 : panel_manager_(panel_manager), | |
| 21 dragging_panel_(NULL), | |
| 22 dragging_panel_original_strip_(NULL) { | |
| 13 } | 23 } |
| 14 | 24 |
| 15 PanelDragController::~PanelDragController() { | 25 PanelDragController::~PanelDragController() { |
| 16 } | 26 } |
| 17 | 27 |
| 18 void PanelDragController::StartDragging(Panel* panel, | 28 void PanelDragController::StartDragging(Panel* panel, |
| 19 const gfx::Point& mouse_location) { | 29 const gfx::Point& mouse_location) { |
| 20 DCHECK(!dragging_panel_); | 30 DCHECK(!dragging_panel_); |
| 21 DCHECK(panel->draggable()); | 31 DCHECK(panel->draggable()); |
| 22 | 32 |
| 23 last_mouse_location_ = mouse_location; | 33 last_mouse_location_ = mouse_location; |
| 34 offset_from_mouse_location_on_drag_start_ = | |
| 35 mouse_location.Subtract(panel->GetBounds().origin()); | |
| 24 | 36 |
| 25 dragging_panel_ = panel; | 37 dragging_panel_ = panel; |
| 26 dragging_panel_original_position_ = panel->GetBounds().origin(); | 38 dragging_panel_->SetPreviewMode(true); |
| 27 | 39 |
| 28 dragging_panel_->panel_strip()->StartDraggingPanel(panel); | 40 // Keep track of original strip and placement for the case that the drag is |
| 41 // cancelled. | |
| 42 dragging_panel_original_strip_ = dragging_panel_->panel_strip(); | |
| 43 dragging_panel_original_strip_->SavePanelPlacement(dragging_panel_); | |
| 44 | |
| 45 dragging_panel_original_strip_->StartDraggingPanelWithinStrip( | |
| 46 dragging_panel_); | |
| 29 } | 47 } |
| 30 | 48 |
| 31 void PanelDragController::Drag(const gfx::Point& mouse_location) { | 49 void PanelDragController::Drag(const gfx::Point& mouse_location) { |
| 32 DCHECK(dragging_panel_); | 50 DCHECK(dragging_panel_); |
| 33 | 51 |
| 34 dragging_panel_->panel_strip()->DragPanel( | 52 PanelStrip* current_strip = dragging_panel_->panel_strip(); |
| 53 | |
| 54 gfx::Rect target_panel_bounds; | |
| 55 PanelStrip* target_strip = ComputeDragTargetStrip( | |
| 56 mouse_location, &target_panel_bounds); | |
| 57 if (target_strip != current_strip) { | |
| 58 // End the dragging in old strip. | |
| 59 current_strip->EndDraggingPanelWithinStrip(dragging_panel_, true); | |
| 60 | |
| 61 // Apply new panel position. | |
| 62 dragging_panel_->SetPanelBounds(target_panel_bounds); | |
| 63 | |
| 64 // Move the panel to new strip. | |
| 65 panel_manager_->MovePanelToStrip(dragging_panel_, | |
| 66 target_strip->type(), | |
| 67 PanelStrip::KNOWN_POSITION); | |
| 68 | |
| 69 // Start the dragging in new strip. | |
| 70 target_strip->StartDraggingPanelWithinStrip(dragging_panel_); | |
| 71 } else { | |
| 72 current_strip->DragPanelWithinStrip( | |
| 35 dragging_panel_, | 73 dragging_panel_, |
| 36 mouse_location.x() - last_mouse_location_.x(), | 74 mouse_location.x() - last_mouse_location_.x(), |
| 37 mouse_location.y() - last_mouse_location_.y()); | 75 mouse_location.y() - last_mouse_location_.y()); |
| 76 } | |
| 38 | 77 |
| 39 last_mouse_location_ = mouse_location; | 78 last_mouse_location_ = mouse_location; |
| 40 } | 79 } |
| 41 | 80 |
| 42 void PanelDragController::EndDragging(bool cancelled) { | 81 void PanelDragController::EndDragging(bool cancelled) { |
| 43 DCHECK(dragging_panel_); | 82 DCHECK(dragging_panel_); |
| 44 | 83 |
| 45 // The code in PanelStrip::EndDraggingPanel might call DragController to find | 84 PanelStrip* current_strip = dragging_panel_->panel_strip(); |
| 46 // out if the drag has ended. So we need to reset |dragging_panel_| to reflect | 85 if (cancelled) { |
| 47 // this. | 86 // Abort the drag in current strip. |
| 48 Panel* panel = dragging_panel_; | 87 current_strip->EndDraggingPanelWithinStrip(dragging_panel_, true); |
| 88 | |
| 89 // Restore the dragging panel to its original strip if needed. | |
| 90 // Note that the bounds of dragging panel is updated later by calling | |
| 91 // RestorePanelToSavedPlacement. | |
| 92 if (current_strip != dragging_panel_original_strip_) { | |
| 93 panel_manager_->MovePanelToStrip( | |
| 94 dragging_panel_, | |
| 95 dragging_panel_original_strip_->type(), | |
| 96 static_cast<PanelStrip::PositioningMask>( | |
|
jennb
2012/03/12 22:43:00
nit: A var might make this more readable than stat
jianli
2012/03/13 00:21:40
Done.
| |
| 97 PanelStrip::DEFAULT_POSITION | PanelStrip::DO_NOT_UPDATE_BOUNDS)); | |
| 98 } | |
| 99 | |
| 100 // End the preview mode. | |
| 101 dragging_panel_->SetPreviewMode(false); | |
| 102 | |
| 103 // Restore the dragging panel to its original placement. | |
| 104 dragging_panel_original_strip_->RestorePanelToSavedPlacement(); | |
| 105 } else { | |
| 106 // The saved placement is not needed. | |
|
jennb
2012/03/12 22:43:00
nit: s/not needed/no longer needed
jianli
2012/03/13 00:21:40
Done.
| |
| 107 dragging_panel_original_strip_->DiscardSavedPanelPlacement(); | |
| 108 | |
| 109 // End the preview mode. | |
| 110 dragging_panel_->SetPreviewMode(false); | |
| 111 | |
| 112 // End the drag. This will cause the panel to be moved to its finalized | |
| 113 // position. | |
| 114 current_strip->EndDraggingPanelWithinStrip(dragging_panel_, false); | |
| 115 } | |
| 116 | |
| 49 dragging_panel_ = NULL; | 117 dragging_panel_ = NULL; |
| 50 panel->panel_strip()->EndDraggingPanel(panel, cancelled); | 118 } |
| 119 | |
| 120 PanelStrip* PanelDragController::ComputeDragTargetStrip( | |
| 121 const gfx::Point& mouse_location, gfx::Rect* new_panel_bounds) const { | |
| 122 if (CanDragToDockedStrip(mouse_location, new_panel_bounds)) | |
| 123 return panel_manager_->docked_strip(); | |
| 124 else if (CanDragToDetachedStrip(mouse_location, new_panel_bounds)) | |
| 125 return panel_manager_->detached_strip(); | |
| 126 else | |
| 127 return dragging_panel_->panel_strip(); | |
| 128 } | |
| 129 | |
| 130 bool PanelDragController::CanDragToDockedStrip( | |
| 131 const gfx::Point& mouse_location, | |
| 132 gfx::Rect* new_panel_bounds) const { | |
| 133 // It has to come from the detached strip. | |
| 134 if (dragging_panel_->panel_strip()->type() != PanelStrip::DETACHED) | |
| 135 return false; | |
| 136 | |
| 137 // Compute target panel bounds. The origin is computed based on the fact that | |
| 138 // the panel should follow the mouse movement. The size remains unchanged. | |
| 139 gfx::Rect target_panel_bounds = dragging_panel_->GetBounds(); | |
| 140 target_panel_bounds.set_origin( | |
| 141 mouse_location.Subtract(offset_from_mouse_location_on_drag_start_)); | |
| 142 | |
| 143 // The bottom of the panel should come very close to or fall below the bottom | |
| 144 // of the docked area. | |
| 145 if (panel_manager_->docked_strip()->display_area().bottom() - | |
| 146 target_panel_bounds.bottom() > | |
| 147 kDockDetachedPanelThreshold) | |
| 148 return false; | |
| 149 | |
| 150 *new_panel_bounds = target_panel_bounds; | |
| 151 return true; | |
| 152 } | |
| 153 | |
| 154 bool PanelDragController::CanDragToDetachedStrip( | |
| 155 const gfx::Point& mouse_location, | |
| 156 gfx::Rect* new_panel_bounds) const { | |
| 157 // It has to come from the docked strip. | |
| 158 if (dragging_panel_->panel_strip()->type() != PanelStrip::DOCKED) | |
| 159 return false; | |
| 160 | |
| 161 // The minimized docked panel is not allowed to detach. | |
| 162 if (dragging_panel_->IsMinimized()) | |
| 163 return false; | |
| 164 | |
| 165 // Compute target panel bounds. The origin is computed based on the fact that | |
| 166 // the panel should follow the mouse movement. The size remains unchanged. | |
| 167 gfx::Rect target_panel_bounds = dragging_panel_->GetBounds(); | |
| 168 target_panel_bounds.set_origin( | |
| 169 mouse_location.Subtract(offset_from_mouse_location_on_drag_start_)); | |
| 170 | |
| 171 // The panel should be dragged up high enough to pass certain threshold. | |
| 172 if (panel_manager_->docked_strip()->display_area().bottom() - | |
| 173 target_panel_bounds.bottom() < | |
| 174 kDetachDockedPanelThreshold) | |
| 175 return false; | |
| 176 | |
| 177 *new_panel_bounds = target_panel_bounds; | |
| 178 return true; | |
| 51 } | 179 } |
| 52 | 180 |
| 53 void PanelDragController::OnPanelClosed(Panel* panel) { | 181 void PanelDragController::OnPanelClosed(Panel* panel) { |
| 54 if (!dragging_panel_) | 182 if (!dragging_panel_) |
| 55 return; | 183 return; |
| 56 | 184 |
| 57 // If the dragging panel is closed, abort the drag. | 185 // If the dragging panel is closed, abort the drag. |
| 58 if (dragging_panel_ == panel) | 186 if (dragging_panel_ == panel) |
| 59 EndDragging(false); | 187 EndDragging(false); |
| 60 } | 188 } |
| OLD | NEW |