12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/docked_panel_drag_handler.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/docked_panel_collection.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/panel.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/panel_manager.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/point.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DockedPanelDragHandler::HandleDrag(Panel* panel, 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Point& target_position) { 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(PanelCollection::DOCKED, panel->collection()->type()); 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DockedPanelCollection* collection = 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<DockedPanelCollection*>(panel->collection()); 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Moves this panel to the dragging position. 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that we still allow the panel to be moved vertically until it gets 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // aligned to the bottom area. 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect new_bounds(panel->GetBounds()); 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_bounds.set_x(target_position.x()); 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int delta_x = new_bounds.x() - panel->GetBounds().x(); 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bottom = collection->GetBottomPositionForExpansionState( 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->expansion_state()); 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (new_bounds.bottom() != bottom) { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_bounds.set_y(target_position.y()); 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (new_bounds.bottom() > bottom) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_bounds.set_y(bottom - new_bounds.height()); 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->SetPanelBoundsInstantly(new_bounds); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (delta_x) { 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Checks and processes other affected panels. 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (delta_x > 0) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DragRight(panel); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DragLeft(panel); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Layout refresh will automatically recompute the bounds of all affected 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // panels due to their position changes. 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collection->RefreshLayout(); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DockedPanelDragHandler::DragLeft(Panel* panel) { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DockedPanelCollection* collection = 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<DockedPanelCollection*>(panel->collection()); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is the left corner of the dragging panel. We use it to check against 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // all the panels on its left. 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int dragging_panel_left_boundary = panel->GetBounds().x(); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Checks the panels to the left of the dragging panel. 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DockedPanelCollection::Panels::iterator dragging_panel_iterator = 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) find(collection->panels_.begin(), collection->panels_.end(), panel); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DockedPanelCollection::Panels::iterator current_panel_iterator = 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dragging_panel_iterator; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++current_panel_iterator; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (; current_panel_iterator != collection->panels_.end(); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++current_panel_iterator) { 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* current_panel = *current_panel_iterator; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Can we swap dragging panel with its left panel? The criterion is that 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the left corner of dragging panel should pass the middle position of 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // its left panel. 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dragging_panel_left_boundary > current_panel->GetBounds().x() + 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_panel->GetBounds().width() / 2) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Swaps the contents and makes |dragging_panel_iterator| refers to the new 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // position. 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *dragging_panel_iterator = current_panel; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *current_panel_iterator = panel; 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dragging_panel_iterator = current_panel_iterator; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DockedPanelDragHandler::DragRight(Panel* panel) { 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DockedPanelCollection* collection = 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<DockedPanelCollection*>(panel->collection()); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is the right corner of the dragging panel. We use it to check against 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // all the panels on its right. 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int dragging_panel_right_boundary = panel->GetBounds().x() + 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->GetBounds().width() - 1; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Checks the panels to the right of the dragging panel. 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DockedPanelCollection::Panels::iterator dragging_panel_iterator = 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) find(collection->panels_.begin(), collection->panels_.end(), panel); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DockedPanelCollection::Panels::iterator current_panel_iterator = 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dragging_panel_iterator; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (current_panel_iterator != collection->panels_.begin()) { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_panel_iterator--; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* current_panel = *current_panel_iterator; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Can we swap dragging panel with its right panel? The criterion is that 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the left corner of dragging panel should pass the middle position of 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // its right panel. 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dragging_panel_right_boundary < current_panel->GetBounds().x() + 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_panel->GetBounds().width() / 2) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Swaps the contents and makes |dragging_panel_iterator| refers to the new 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // position. 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *dragging_panel_iterator = current_panel; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *current_panel_iterator = panel; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dragging_panel_iterator = current_panel_iterator; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 116