Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(411)

Side by Side Diff: chrome/browser/ui/panels/panel_drag_controller.cc

Issue 9546001: Support detaching/attaching panels via inter-strip drags. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
10 13
11 PanelDragController::PanelDragController() 14 namespace {
12 : dragging_panel_(NULL) { 15
16 // The threshold to detach the docked panel to make it free-floating.
17 const int kDetachDockedPanelThreshold = -80;
jennb 2012/03/01 00:33:38 Thresholds are usually positive amounts.
jianli 2012/03/02 22:42:43 Done.
18
19 // The threshold to dock the detached panel.
20 const int kDockDetachedPanelThreshold = -10;
21
22 } // namespace
23
24 PanelDragController::PanelDragController(PanelManager* panel_manager)
25 : panel_manager_(panel_manager),
26 dragging_panel_(NULL),
27 dragging_panel_original_strip_(NULL),
28 has_dragged_to_other_strip_(false) {
13 } 29 }
14 30
15 PanelDragController::~PanelDragController() { 31 PanelDragController::~PanelDragController() {
16 } 32 }
17 33
18 void PanelDragController::StartDragging(Panel* panel) { 34 void PanelDragController::StartDragging(Panel* panel,
35 const gfx::Point& mouse_location) {
19 DCHECK(!dragging_panel_); 36 DCHECK(!dragging_panel_);
20 DCHECK(panel->draggable()); 37 DCHECK(panel->draggable());
21 38
22 dragging_panel_ = panel; 39 dragging_panel_ = panel;
40 dragging_panel_original_strip_ = dragging_panel_->panel_strip();
23 dragging_panel_original_position_ = panel->GetBounds().origin(); 41 dragging_panel_original_position_ = panel->GetBounds().origin();
42 has_dragged_to_other_strip_ = false;
43 total_ommitted_delta_y_ = 0;
jennb 2012/03/01 00:33:38 Seems cleaner to store original mouse location at
jianli 2012/03/02 22:42:43 Removed. We now use original mouse location at sta
24 44
25 dragging_panel_->panel_strip()->StartDraggingPanel(panel); 45 // When the detached panel is being dragged, it should be always-on-top. This
46 // is to make sure it will not get obscured by other docked panels.
47 if (dragging_panel_original_strip_->type() == PanelStrip::DETACHED)
48 panel->SetAlwaysOnTop(true);
jennb 2012/03/01 00:33:38 Always-on-top should only be set if panel is in th
jianli 2012/03/02 22:42:43 Done.
49
50 dragging_panel_original_strip_->StartDraggingPanel(panel);
51
52 last_mouse_location_ = mouse_location;
26 } 53 }
27 54
28 void PanelDragController::Drag(int delta_x, int delta_y) { 55 void PanelDragController::Drag(const gfx::Point& mouse_location) {
29 DCHECK(dragging_panel_); 56 DCHECK(dragging_panel_);
30 57
31 dragging_panel_->panel_strip()->DragPanel(dragging_panel_, delta_x, delta_y); 58 int delta_x = mouse_location.x() - last_mouse_location_.x();
59 int delta_y = mouse_location.y() - last_mouse_location_.y();
60
61 PanelStrip* strip_to_drag_to = CanDragToDockedStrip(mouse_location);
jennb 2012/03/01 00:33:38 PanelStrip* target_strip = ComputeDragTarget(mouse
jianli 2012/03/02 22:42:43 Done.
62 if (!strip_to_drag_to)
63 strip_to_drag_to = CanDragToDetachedStrip(mouse_location);
64
65 if (strip_to_drag_to) {
66 has_dragged_to_other_strip_ = true;
67
68 // Compensate all the y-coordinate drag movements that could be omitted
69 // in previous intra-strip drag.
70 gfx::Point new_position = dragging_panel_->GetBounds().origin();
71 new_position.Offset(delta_x, delta_y + total_ommitted_delta_y_);
72 total_ommitted_delta_y_ = 0;
73
74 MoveToStrip(dragging_panel_, strip_to_drag_to, new_position);
75 } else {
76 gfx::Point old_position = dragging_panel_->GetBounds().origin();
77 dragging_panel_->panel_strip()->DragPanel(dragging_panel_,
78 delta_x,
79 delta_y);
80
81 // Track all the y-coordinate drag movements that could be omitted
82 // in previous intra-strip drag.
83 gfx::Point new_position = dragging_panel_->GetBounds().origin();
84 total_ommitted_delta_y_ += delta_y - new_position.y() + old_position.y();
85 }
86
87 last_mouse_location_ = mouse_location;
32 } 88 }
33 89
34 void PanelDragController::EndDragging(bool cancelled) { 90 void PanelDragController::EndDragging(bool cancelled) {
35 DCHECK(dragging_panel_); 91 DCHECK(dragging_panel_);
36 92
37 // The code in PanelStrip::EndDraggingPanel might call DragController to find 93 // The code in PanelStrip::EndDraggingPanel might call DragController to find
38 // out if the drag has ended. So we need to reset |dragging_panel_| to reflect 94 // out if the drag has ended. So we need to reset |dragging_panel_| to reflect
39 // this. 95 // this.
40 Panel* panel = dragging_panel_; 96 Panel* panel = dragging_panel_;
41 dragging_panel_ = NULL; 97 dragging_panel_ = NULL;
98
99 // If the drag is cancelled and the dragging panel is still in the different
100 // strip from the original strip, put it back to the original strip first.
101 if (cancelled && panel->panel_strip() != dragging_panel_original_strip_) {
jennb 2012/03/01 00:33:38 I'm having a hard time picturing what happens here
jianli 2012/03/02 22:42:43 Changed per discussed.
102 MoveToStrip(panel,
103 dragging_panel_original_strip_,
104 panel->GetBounds().origin());
105 }
106
42 panel->panel_strip()->EndDraggingPanel(panel, cancelled); 107 panel->panel_strip()->EndDraggingPanel(panel, cancelled);
108
109 // When the drag ends, the dragging panel will stop staying always-on-top if
110 // it ends with the detached state.
111 if (panel->panel_strip()->type() == PanelStrip::DETACHED)
112 panel->SetAlwaysOnTop(false);
jennb 2012/03/01 00:33:38 Again, it seems like the responsibility of the str
jianli 2012/03/02 22:42:43 Done.
113 }
114
115 PanelStrip* PanelDragController::CanDragToDockedStrip(
jennb 2012/03/01 00:33:38 Seems like this function and CanDragToDetachedStri
jianli 2012/03/02 22:42:43 I think it is cleaner to split the different check
116 const gfx::Point& mouse_location) const {
117 // It has to come from the detached strip.
118 if (dragging_panel_->panel_strip()->type() != PanelStrip::DETACHED)
119 return NULL;
120
121 // The bottom of the panel should come very close to or fall below the bottom
122 // of the docked area.
123 int new_panel_bottom = dragging_panel_->GetBounds().bottom() +
jennb 2012/03/01 00:33:38 Would it be cleaner to do computations using start
jianli 2012/03/02 22:42:43 The triggering condition for attach is to check th
124 mouse_location.y() - last_mouse_location_.y();
125 int docked_area_bottom =
126 panel_manager_->docked_strip()->display_area().bottom();
jennb 2012/03/01 00:33:38 Should dock strip be the one to decide if a panel
jianli 2012/03/02 22:42:43 Docked strip can only decide if a docked panel can
127 if (new_panel_bottom - docked_area_bottom < kDockDetachedPanelThreshold)
jennb 2012/03/03 02:19:33 if new_panel_bottom is above the bottom of the doc
128 return NULL;
129
130 return panel_manager_->docked_strip();
131 }
132
133 PanelStrip* PanelDragController::CanDragToDetachedStrip(
134 const gfx::Point& mouse_location) const {
135 // It has to come from the docked strip.
136 if (dragging_panel_->panel_strip()->type() != PanelStrip::DOCKED)
137 return NULL;
138
139 // The minimized docked panel is not allowed to detach.
140 if (dragging_panel_->expansion_state() != Panel::EXPANDED)
141 return NULL;
142
143 // The panel should be dragged up higher enough to pass certain threshold.
144 int delta_y = total_ommitted_delta_y_ +
145 mouse_location.y() - last_mouse_location_.y();
146 if (delta_y > kDetachDockedPanelThreshold)
147 return NULL;
148
149 return panel_manager_->detached_strip();
150 }
151
152 void PanelDragController::MoveToStrip(Panel* panel,
153 PanelStrip* new_strip,
154 const gfx::Point& new_position) {
155 // Stop dragging in old strip. This needs to be done before moving the panel.
156 PanelStrip* old_strip = panel->panel_strip();
157 old_strip->EndDraggingPanel(panel, false);
jennb 2012/03/01 00:33:38 Confusing. Dragging isn't really ended. For instan
jianli 2012/03/02 22:42:43 Per discussion, this is what we want.
158
159 // Move the panel to new strip.
jennb 2012/03/01 00:33:38 I'd prefer if moving a panel between strips was al
jianli 2012/03/02 22:42:43 I agree. I would merge with your patch later.
160 old_strip->RemovePanel(panel);
161 panel->set_panel_strip(new_strip);
162 new_strip->AddPanelAtPosition(panel, new_position);
163
164 // Start dragging in new strip.
165 new_strip->StartDraggingPanel(panel);
jennb 2012/03/01 00:33:38 Very weird logic flow: EndDragging() MoveToStrip(
jianli 2012/03/02 22:42:43 Per discussion, this is what we want. Renamed drag
43 } 166 }
44 167
45 void PanelDragController::OnPanelClosed(Panel* panel) { 168 void PanelDragController::OnPanelClosed(Panel* panel) {
46 if (!dragging_panel_) 169 if (!dragging_panel_)
47 return; 170 return;
48 171
49 // If the dragging panel is closed, abort the drag. 172 // If the dragging panel is closed, abort the drag.
50 if (dragging_panel_ == panel) 173 if (dragging_panel_ == panel)
51 EndDragging(false); 174 EndDragging(false);
52 } 175 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698