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

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

Issue 9403035: Refactor intra-strip panel drags by introducing PanelDragController. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix per feedback Created 8 years, 10 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/docked_panel_strip.h" 5 #include "chrome/browser/ui/panels/docked_panel_strip.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "chrome/browser/ui/browser.h" 12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/panels/overflow_panel_strip.h" 13 #include "chrome/browser/ui/panels/overflow_panel_strip.h"
14 #include "chrome/browser/ui/panels/panel_drag_controller.h"
14 #include "chrome/browser/ui/panels/panel_manager.h" 15 #include "chrome/browser/ui/panels/panel_manager.h"
15 #include "chrome/browser/ui/panels/panel_mouse_watcher.h" 16 #include "chrome/browser/ui/panels/panel_mouse_watcher.h"
16 #include "chrome/common/chrome_notification_types.h" 17 #include "chrome/common/chrome_notification_types.h"
17 #include "content/public/browser/notification_service.h" 18 #include "content/public/browser/notification_service.h"
18 #include "content/public/browser/notification_source.h" 19 #include "content/public/browser/notification_source.h"
19 20
20 namespace { 21 namespace {
21 // Width to height ratio is used to compute the default width or height 22 // Width to height ratio is used to compute the default width or height
22 // when only one value is provided. 23 // when only one value is provided.
23 const double kPanelDefaultWidthToHeightRatio = 1.62; // golden ratio 24 const double kPanelDefaultWidthToHeightRatio = 1.62; // golden ratio
(...skipping 28 matching lines...) Expand all
52 // static 53 // static
53 const int DockedPanelStrip::kPanelMinWidth = 100; 54 const int DockedPanelStrip::kPanelMinWidth = 100;
54 const int DockedPanelStrip::kPanelMinHeight = 20; 55 const int DockedPanelStrip::kPanelMinHeight = 20;
55 56
56 DockedPanelStrip::DockedPanelStrip(PanelManager* panel_manager) 57 DockedPanelStrip::DockedPanelStrip(PanelManager* panel_manager)
57 : PanelStrip(PanelStrip::DOCKED), 58 : PanelStrip(PanelStrip::DOCKED),
58 panel_manager_(panel_manager), 59 panel_manager_(panel_manager),
59 minimized_panel_count_(0), 60 minimized_panel_count_(0),
60 are_titlebars_up_(false), 61 are_titlebars_up_(false),
61 disable_layout_refresh_(false), 62 disable_layout_refresh_(false),
62 dragging_panel_(NULL),
63 dragging_panel_original_x_(0), 63 dragging_panel_original_x_(0),
64 delayed_titlebar_action_(NO_ACTION), 64 delayed_titlebar_action_(NO_ACTION),
65 titlebar_action_factory_(this) { 65 titlebar_action_factory_(this) {
66 } 66 }
67 67
68 DockedPanelStrip::~DockedPanelStrip() { 68 DockedPanelStrip::~DockedPanelStrip() {
69 DCHECK(panels_.empty()); 69 DCHECK(panels_.empty());
70 DCHECK(panels_pending_to_remove_.empty());
71 DCHECK(panels_in_temporary_layout_.empty()); 70 DCHECK(panels_in_temporary_layout_.empty());
72 DCHECK_EQ(0, minimized_panel_count_); 71 DCHECK_EQ(0, minimized_panel_count_);
73 } 72 }
74 73
75 void DockedPanelStrip::SetDisplayArea(const gfx::Rect& display_area) { 74 void DockedPanelStrip::SetDisplayArea(const gfx::Rect& display_area) {
76 if (display_area_ == display_area) 75 if (display_area_ == display_area)
77 return; 76 return;
78 77
79 gfx::Rect old_area = display_area_; 78 gfx::Rect old_area = display_area_;
80 display_area_ = display_area; 79 display_area_ = display_area;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 panel), 175 panel),
177 base::TimeDelta::FromMilliseconds(PanelManager::AdjustTimeInterval( 176 base::TimeDelta::FromMilliseconds(PanelManager::AdjustTimeInterval(
178 kMoveNewPanelToOverflowDelayMs))); 177 kMoveNewPanelToOverflowDelayMs)));
179 } 178 }
180 #endif 179 #endif
181 panel->Initialize(gfx::Rect(x, y, width, height)); 180 panel->Initialize(gfx::Rect(x, y, width, height));
182 } 181 }
183 182
184 // Set panel properties for this strip. 183 // Set panel properties for this strip.
185 panel->SetAppIconVisibility(true); 184 panel->SetAppIconVisibility(true);
186 panel->set_draggable(!panel->has_temporary_layout());
187 panel->ApplyVisualStyleForStrip(); 185 panel->ApplyVisualStyleForStrip();
188 186
189 if (panel->has_temporary_layout()) 187 if (panel->has_temporary_layout())
190 panels_in_temporary_layout_.insert(panel); 188 panels_in_temporary_layout_.insert(panel);
191 else 189 else
192 panels_.push_back(panel); 190 panels_.push_back(panel);
193 } 191 }
194 192
195 int DockedPanelStrip::GetMaxPanelWidth() const { 193 int DockedPanelStrip::GetMaxPanelWidth() const {
196 return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor); 194 return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor);
197 } 195 }
198 196
199 int DockedPanelStrip::GetMaxPanelHeight() const { 197 int DockedPanelStrip::GetMaxPanelHeight() const {
200 return display_area_.height(); 198 return display_area_.height();
201 } 199 }
202 200
203 int DockedPanelStrip::StartingRightPosition() const { 201 int DockedPanelStrip::StartingRightPosition() const {
204 return display_area_.right(); 202 return display_area_.right();
205 } 203 }
206 204
207 int DockedPanelStrip::GetRightMostAvailablePosition() const { 205 int DockedPanelStrip::GetRightMostAvailablePosition() const {
208 return panels_.empty() ? StartingRightPosition() : 206 return panels_.empty() ? StartingRightPosition() :
209 (panels_.back()->GetBounds().x() - kPanelsHorizontalSpacing); 207 (panels_.back()->GetBounds().x() - kPanelsHorizontalSpacing);
210 } 208 }
211 209
212 bool DockedPanelStrip::RemovePanel(Panel* panel) { 210 bool DockedPanelStrip::RemovePanel(Panel* panel) {
211 bool refresh_layout = !disable_layout_refresh_;
213 if (panel->has_temporary_layout()) { 212 if (panel->has_temporary_layout()) {
214 panels_in_temporary_layout_.erase(panel); 213 panels_in_temporary_layout_.erase(panel);
215 return true; 214 refresh_layout = false;
jennb 2012/02/17 21:28:45 Keep this 'return true'. No need for refresh_layou
jianli 2012/02/17 23:52:56 Per discussion, remove the change from this patch.
215 } else {
216 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel);
217 if (iter == panels_.end())
218 return false;
219
220 if (panel->expansion_state() != Panel::EXPANDED)
221 DecrementMinimizedPanels();
222
223 panels_.erase(iter);
216 } 224 }
217 225
218 if (find(panels_.begin(), panels_.end(), panel) == panels_.end()) 226 panel_manager_->OnPanelRemoved(panel);
jennb 2012/02/17 21:28:45 Move this right after erase(iter) so notification
jianli 2012/02/17 23:52:56 Per discussion, remove the change from this patch.
219 return false;
220 227
221 // If we're in the process of dragging, delay the removal. 228 if (refresh_layout)
222 if (dragging_panel_) {
223 panels_pending_to_remove_.push_back(panel);
224 return true;
225 }
226
227 DoRemove(panel);
228
229 if (!disable_layout_refresh_)
230 RefreshLayout(); 229 RefreshLayout();
231 230
232 return true; 231 return true;
233 } 232 }
234 233
235 void DockedPanelStrip::DelayedRemove() { 234 bool DockedPanelStrip::CanDragPanel(Panel* panel) const {
236 for (size_t i = 0; i < panels_pending_to_remove_.size(); ++i) 235 // Only the panels having temporary layout can't be dragged.
237 DoRemove(panels_pending_to_remove_[i]); 236 return !panel->has_temporary_layout();
238 panels_pending_to_remove_.clear();
239 RefreshLayout();
240 } 237 }
241 238
242 bool DockedPanelStrip::DoRemove(Panel* panel) { 239 void DockedPanelStrip::StartDraggingPanel(Panel* panel) {
243 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel);
244 if (iter == panels_.end())
245 return false;
246
247 if (panel->expansion_state() != Panel::EXPANDED)
248 DecrementMinimizedPanels();
249
250 panels_.erase(iter);
251 panel_manager_->OnPanelRemoved(panel);
252 return true;
253 }
254
255 void DockedPanelStrip::StartDragging(Panel* panel) {
256 dragging_panel_iterator_ = find(panels_.begin(), panels_.end(), panel); 240 dragging_panel_iterator_ = find(panels_.begin(), panels_.end(), panel);
257 DCHECK(dragging_panel_iterator_ != panels_.end()); 241 DCHECK(dragging_panel_iterator_ != panels_.end());
258 242
259 dragging_panel_ = panel;
260 dragging_panel_bounds_ = panel->GetBounds(); 243 dragging_panel_bounds_ = panel->GetBounds();
261 dragging_panel_original_x_ = dragging_panel_bounds_.x(); 244 dragging_panel_original_x_ = dragging_panel_bounds_.x();
262 } 245 }
263 246
264 void DockedPanelStrip::Drag(int delta_x) { 247 void DockedPanelStrip::DragPanel(int delta_x, int delta_y) {
265 DCHECK(dragging_panel_);
266
267 if (!delta_x) 248 if (!delta_x)
268 return; 249 return;
269 250
251 Panel* dragging_panel = panel_manager_->drag_controller()->dragging_panel();
252 DCHECK(dragging_panel);
253
270 // Moves this panel to the dragging position. 254 // Moves this panel to the dragging position.
271 gfx::Rect new_bounds(dragging_panel_->GetBounds()); 255 gfx::Rect new_bounds(dragging_panel->GetBounds());
272 new_bounds.set_x(new_bounds.x() + delta_x); 256 new_bounds.set_x(new_bounds.x() + delta_x);
273 dragging_panel_->SetPanelBounds(new_bounds); 257 dragging_panel->SetPanelBounds(new_bounds);
274 258
275 // Checks and processes other affected panels. 259 // Checks and processes other affected panels.
276 if (delta_x > 0) 260 if (delta_x > 0)
277 DragRight(); 261 DragRight(dragging_panel);
278 else 262 else
279 DragLeft(); 263 DragLeft(dragging_panel);
280 } 264 }
281 265
282 void DockedPanelStrip::DragLeft() { 266 void DockedPanelStrip::DragLeft(Panel* dragging_panel) {
283 // This is the left corner of the dragging panel. We use it to check against 267 // This is the left corner of the dragging panel. We use it to check against
284 // all the panels on its left. 268 // all the panels on its left.
285 int dragging_panel_left_boundary = dragging_panel_->GetBounds().x(); 269 int dragging_panel_left_boundary = dragging_panel->GetBounds().x();
286 270
287 // This is the right corner which a panel will be moved to. 271 // This is the right corner which a panel will be moved to.
288 int current_panel_right_boundary = 272 int current_panel_right_boundary =
289 dragging_panel_bounds_.x() + dragging_panel_bounds_.width(); 273 dragging_panel_bounds_.x() + dragging_panel_bounds_.width();
290 274
291 // Checks the panels to the left of the dragging panel. 275 // Checks the panels to the left of the dragging panel.
292 Panels::iterator current_panel_iterator = dragging_panel_iterator_; 276 Panels::iterator current_panel_iterator = dragging_panel_iterator_;
293 ++current_panel_iterator; 277 ++current_panel_iterator;
294 for (; current_panel_iterator != panels_.end(); ++current_panel_iterator) { 278 for (; current_panel_iterator != panels_.end(); ++current_panel_iterator) {
295 Panel* current_panel = *current_panel_iterator; 279 Panel* current_panel = *current_panel_iterator;
296 280
297 // Current panel will only be affected if the left corner of dragging 281 // Current panel will only be affected if the left corner of dragging
298 // panel goes beyond the middle position of the current panel. 282 // panel goes beyond the middle position of the current panel.
299 if (dragging_panel_left_boundary > current_panel->GetBounds().x() + 283 if (dragging_panel_left_boundary > current_panel->GetBounds().x() +
300 current_panel->GetBounds().width() / 2) 284 current_panel->GetBounds().width() / 2)
301 break; 285 break;
302 286
303 // Moves current panel to the new position. 287 // Moves current panel to the new position.
304 gfx::Rect bounds(current_panel->GetBounds()); 288 gfx::Rect bounds(current_panel->GetBounds());
305 bounds.set_x(current_panel_right_boundary - bounds.width()); 289 bounds.set_x(current_panel_right_boundary - bounds.width());
306 current_panel_right_boundary -= bounds.width() + kPanelsHorizontalSpacing; 290 current_panel_right_boundary -= bounds.width() + kPanelsHorizontalSpacing;
307 current_panel->SetPanelBounds(bounds); 291 current_panel->SetPanelBounds(bounds);
308 292
309 // Swaps current panel and dragging panel. 293 // Swaps current panel and dragging panel.
310 *dragging_panel_iterator_ = current_panel; 294 *dragging_panel_iterator_ = current_panel;
311 *current_panel_iterator = dragging_panel_; 295 *current_panel_iterator = dragging_panel;
312 dragging_panel_iterator_ = current_panel_iterator; 296 dragging_panel_iterator_ = current_panel_iterator;
313 } 297 }
314 298
315 // Updates the potential final position of dragging panel as the result of 299 // Updates the potential final position of dragging panel as the result of
316 // swapping with panels on its left. 300 // swapping with panels on its left.
317 dragging_panel_bounds_.set_x(current_panel_right_boundary - 301 dragging_panel_bounds_.set_x(current_panel_right_boundary -
318 dragging_panel_bounds_.width()); 302 dragging_panel_bounds_.width());
319 } 303 }
320 304
321 void DockedPanelStrip::DragRight() { 305 void DockedPanelStrip::DragRight(Panel* dragging_panel) {
322 // This is the right corner of the dragging panel. We use it to check against 306 // This is the right corner of the dragging panel. We use it to check against
323 // all the panels on its right. 307 // all the panels on its right.
324 int dragging_panel_right_boundary = dragging_panel_->GetBounds().x() + 308 int dragging_panel_right_boundary = dragging_panel->GetBounds().x() +
325 dragging_panel_->GetBounds().width() - 1; 309 dragging_panel->GetBounds().width() - 1;
326 310
327 // This is the left corner which a panel will be moved to. 311 // This is the left corner which a panel will be moved to.
328 int current_panel_left_boundary = dragging_panel_bounds_.x(); 312 int current_panel_left_boundary = dragging_panel_bounds_.x();
329 313
330 // Checks the panels to the right of the dragging panel. 314 // Checks the panels to the right of the dragging panel.
331 Panels::iterator current_panel_iterator = dragging_panel_iterator_; 315 Panels::iterator current_panel_iterator = dragging_panel_iterator_;
332 while (current_panel_iterator != panels_.begin()) { 316 while (current_panel_iterator != panels_.begin()) {
333 current_panel_iterator--; 317 current_panel_iterator--;
334 Panel* current_panel = *current_panel_iterator; 318 Panel* current_panel = *current_panel_iterator;
335 319
336 // Current panel will only be affected if the right corner of dragging 320 // Current panel will only be affected if the right corner of dragging
337 // panel goes beyond the middle position of the current panel. 321 // panel goes beyond the middle position of the current panel.
338 if (dragging_panel_right_boundary < current_panel->GetBounds().x() + 322 if (dragging_panel_right_boundary < current_panel->GetBounds().x() +
339 current_panel->GetBounds().width() / 2) 323 current_panel->GetBounds().width() / 2)
340 break; 324 break;
341 325
342 // Moves current panel to the new position. 326 // Moves current panel to the new position.
343 gfx::Rect bounds(current_panel->GetBounds()); 327 gfx::Rect bounds(current_panel->GetBounds());
344 bounds.set_x(current_panel_left_boundary); 328 bounds.set_x(current_panel_left_boundary);
345 current_panel_left_boundary += bounds.width() + kPanelsHorizontalSpacing; 329 current_panel_left_boundary += bounds.width() + kPanelsHorizontalSpacing;
346 current_panel->SetPanelBounds(bounds); 330 current_panel->SetPanelBounds(bounds);
347 331
348 // Swaps current panel and dragging panel. 332 // Swaps current panel and dragging panel.
349 *dragging_panel_iterator_ = current_panel; 333 *dragging_panel_iterator_ = current_panel;
350 *current_panel_iterator = dragging_panel_; 334 *current_panel_iterator = dragging_panel;
351 dragging_panel_iterator_ = current_panel_iterator; 335 dragging_panel_iterator_ = current_panel_iterator;
352 } 336 }
353 337
354 // Updates the potential final position of dragging panel as the result of 338 // Updates the potential final position of dragging panel as the result of
355 // swapping with panels on its right. 339 // swapping with panels on its right.
356 dragging_panel_bounds_.set_x(current_panel_left_boundary); 340 dragging_panel_bounds_.set_x(current_panel_left_boundary);
357 } 341 }
358 342
359 void DockedPanelStrip::EndDragging(bool cancelled) { 343 void DockedPanelStrip::EndDraggingPanel(bool cancelled) {
360 DCHECK(dragging_panel_); 344 Panel* dragging_panel = panel_manager_->drag_controller()->dragging_panel();
345 DCHECK(dragging_panel);
361 346
362 if (cancelled) 347 if (cancelled)
363 Drag(dragging_panel_original_x_ - dragging_panel_->GetBounds().x()); 348 DragPanel(dragging_panel_original_x_ - dragging_panel->GetBounds().x(), 0);
364 else 349 else
365 dragging_panel_->SetPanelBounds(dragging_panel_bounds_); 350 dragging_panel->SetPanelBounds(dragging_panel_bounds_);
366
367 dragging_panel_ = NULL;
368
369 DelayedRemove();
370 } 351 }
371 352
372 void DockedPanelStrip::OnPanelExpansionStateChanged(Panel* panel) { 353 void DockedPanelStrip::OnPanelExpansionStateChanged(Panel* panel) {
373 gfx::Size size = panel->restored_size(); 354 gfx::Size size = panel->restored_size();
374 Panel::ExpansionState expansion_state = panel->expansion_state(); 355 Panel::ExpansionState expansion_state = panel->expansion_state();
375 Panel::ExpansionState old_state = panel->old_expansion_state(); 356 Panel::ExpansionState old_state = panel->old_expansion_state();
376 switch (expansion_state) { 357 switch (expansion_state) {
377 case Panel::EXPANDED: 358 case Panel::EXPANDED:
378 if (old_state == Panel::TITLE_ONLY || old_state == Panel::MINIMIZED) 359 if (old_state == Panel::TITLE_ONLY || old_state == Panel::MINIMIZED)
379 DecrementMinimizedPanels(); 360 DecrementMinimizedPanels();
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 for (Panels::const_iterator iter = panels_.begin(); 498 for (Panels::const_iterator iter = panels_.begin();
518 iter != panels_.end(); ++iter) { 499 iter != panels_.end(); ++iter) {
519 Panel* panel = *iter; 500 Panel* panel = *iter;
520 Panel::ExpansionState state = panel->expansion_state(); 501 Panel::ExpansionState state = panel->expansion_state();
521 // Skip the expanded panel. 502 // Skip the expanded panel.
522 if (state == Panel::EXPANDED) 503 if (state == Panel::EXPANDED)
523 continue; 504 continue;
524 505
525 // If the panel is showing titlebar only, we want to keep it up when it is 506 // If the panel is showing titlebar only, we want to keep it up when it is
526 // being dragged. 507 // being dragged.
527 if (state == Panel::TITLE_ONLY && is_dragging_panel()) 508 if (state == Panel::TITLE_ONLY) {
528 return true; 509 Panel* dragging_panel =
jennb 2012/02/17 21:28:45 shouldn't this be: if (state == title_only && dra
jianli 2012/02/17 23:52:56 Done.
510 panel_manager_->drag_controller()->dragging_panel();
511 if (dragging_panel && dragging_panel->panel_strip() == this)
512 return true;
513 }
529 514
530 // We do not want to bring up other minimized panels if the mouse is over 515 // We do not want to bring up other minimized panels if the mouse is over
531 // the panel that pops up the titlebar to attract attention. 516 // the panel that pops up the titlebar to attract attention.
532 if (panel->IsDrawingAttention()) 517 if (panel->IsDrawingAttention())
533 continue; 518 continue;
534 519
535 gfx::Rect bounds = panel->GetBounds(); 520 gfx::Rect bounds = panel->GetBounds();
536 if (bounds.x() <= mouse_x && mouse_x <= bounds.right() && 521 if (bounds.x() <= mouse_x && mouse_x <= bounds.right() &&
537 mouse_y >= bounds.y()) 522 mouse_y >= bounds.y())
538 return true; 523 return true;
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 722
738 void DockedPanelStrip::DelayedMovePanelToOverflow(Panel* panel) { 723 void DockedPanelStrip::DelayedMovePanelToOverflow(Panel* panel) {
739 if (panels_in_temporary_layout_.erase(panel)) { 724 if (panels_in_temporary_layout_.erase(panel)) {
740 DCHECK(panel->has_temporary_layout()); 725 DCHECK(panel->has_temporary_layout());
741 panel->MoveToStrip(panel_manager_->overflow_strip()); 726 panel->MoveToStrip(panel_manager_->overflow_strip());
742 } 727 }
743 } 728 }
744 729
745 void DockedPanelStrip::CloseAll() { 730 void DockedPanelStrip::CloseAll() {
746 // This should only be called at the end of tests to clean up. 731 // This should only be called at the end of tests to clean up.
747 DCHECK(!dragging_panel_);
748 DCHECK(panels_in_temporary_layout_.empty()); 732 DCHECK(panels_in_temporary_layout_.empty());
749 733
750 // Make a copy of the iterator as closing panels can modify the vector. 734 // Make a copy of the iterator as closing panels can modify the vector.
751 Panels panels_copy = panels_; 735 Panels panels_copy = panels_;
752 736
753 // Start from the bottom to avoid reshuffling. 737 // Start from the bottom to avoid reshuffling.
754 for (Panels::reverse_iterator iter = panels_copy.rbegin(); 738 for (Panels::reverse_iterator iter = panels_copy.rbegin();
755 iter != panels_copy.rend(); ++iter) 739 iter != panels_copy.rend(); ++iter)
756 (*iter)->Close(); 740 (*iter)->Close();
757 } 741 }
758
759 bool DockedPanelStrip::is_dragging_panel() const {
760 return dragging_panel_ != NULL;
761 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698