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 |