1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file. 4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/panels/panel_manager.h" 6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <algorithm> 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/logging.h" 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/scoped_ptr.h" 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser.h" 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/panels/panel.h" 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/window_sizer.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace { 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Invalid panel index. 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst size_t kInvalidPanelIndex = static_cast<size_t>(-1); 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Minimum width and height of a panel. 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int kPanelMinWidthPixels = 64; 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int kPanelMinHeightPixels = 24; 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Default width and height of a panel. 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int kPanelDefaultWidthPixels = 240; 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int kPanelDefaultHeightPixels = 290; 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Maxmium width and height of a panel based on the factor of the working 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// area. 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst double kPanelMaxWidthFactor = 1.0; 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst double kPanelMaxHeightFactor = 0.5; 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Horizontal spacing between two panels. 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int kPanelsHorizontalSpacing = 4; 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Single instance of PanelManager. 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenscoped_ptr<PanelManager> panel_instance; 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenPanelManager* PanelManager::GetInstance() { 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!panel_instance.get()) { 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen panel_instance.reset(new PanelManager()); 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return panel_instance.get(); 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenPanelManager::PanelManager() 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : max_width_(0), 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen max_height_(0), 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen min_x_(0), 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen current_x_(0), 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bottom_edge_y_(0), 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dragging_panel_index_(kInvalidPanelIndex), 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dragging_panel_original_x_(0) { 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen OnDisplayChanged(); 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenPanelManager::~PanelManager() { 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(active_panels_.empty()); 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(pending_panels_.empty()); 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(panels_pending_to_remove_.empty()); 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::OnDisplayChanged() { 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<WindowSizer::MonitorInfoProvider> info_provider( 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen WindowSizer::CreateDefaultMonitorInfoProvider()); 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Rect work_area = info_provider->GetPrimaryMonitorWorkArea(); 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen min_x_ = work_area.x(); 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen current_x_ = work_area.right(); 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bottom_edge_y_ = work_area.bottom(); 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen max_width_ = static_cast<int>(work_area.width() * kPanelMaxWidthFactor); 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen max_height_ = static_cast<int>(work_area.height() * kPanelMaxHeightFactor); 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Rearrange(active_panels_.begin()); 75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenPanel* PanelManager::CreatePanel(Browser* browser) { 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Rect bounds = browser->override_bounds(); 79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool is_within_bounds = ComputeBoundsForNextPanel(&bounds, true); 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Panel* panel = new Panel(browser, bounds); 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (is_within_bounds) 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_.push_back(panel); 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen else 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pending_panels_.push_back(panel); 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return panel; 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::ProcessPending() { 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen while (!pending_panels_.empty()) { 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Panel* panel = pending_panels_.front(); 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Rect bounds = panel->bounds(); 94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (ComputeBoundsForNextPanel(&bounds, true)) { 95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(jianli): More work to support displaying pending panels. 96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_.push_back(panel); 97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pending_panels_.pop_front(); 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::Remove(Panel* panel) { 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If we're in the process of dragging, delay the removal. 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (dragging_panel_index_ != kInvalidPanelIndex) { 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen panels_pending_to_remove_.push_back(panel); 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DoRemove(panel); 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::DelayedRemove() { 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < panels_pending_to_remove_.size(); ++i) 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DoRemove(panels_pending_to_remove_[i]); 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen panels_pending_to_remove_.clear(); 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::DoRemove(Panel* panel) { 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Checks the active panel list. 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ActivePanels::iterator iter = 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen find(active_panels_.begin(), active_panels_.end(), panel); 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (iter == active_panels_.end()) { 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Checks the pending panel list. 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PendingPanels::iterator iter2 = 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen find(pending_panels_.begin(), pending_panels_.end(), panel); 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (iter2 != pending_panels_.end()) 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pending_panels_.erase(iter2); 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen current_x_ = (*iter)->bounds().x() + (*iter)->bounds().width(); 132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Rearrange(active_panels_.erase(iter)); 133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProcessPending(); 135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::StartDragging(Panel* panel) { 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < active_panels_.size(); ++i) { 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (active_panels_[i] == panel) { 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dragging_panel_index_ = i; 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dragging_panel_bounds_ = panel->bounds(); 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dragging_panel_original_x_ = dragging_panel_bounds_.x(); 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::Drag(int delta_x) { 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(dragging_panel_index_ != kInvalidPanelIndex); 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!delta_x) 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Moves this panel to the dragging position. 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Rect new_bounds(active_panels_[dragging_panel_index_]->bounds()); 156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new_bounds.set_x(new_bounds.x() + delta_x); 157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_[dragging_panel_index_]->SetBounds(new_bounds); 158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Checks and processes other affected panels. 160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (delta_x > 0) 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DragPositive(delta_x); 162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen else 163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DragNegative(delta_x); 164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::DragNegative(int delta_x) { 167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(delta_x < 0); 168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Panel* dragging_panel = active_panels_[dragging_panel_index_]; 170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // This is the left corner of the dragging panel. We use it to check against 172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // all the panels on its left. 173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int dragging_panel_x = dragging_panel->bounds().x() + delta_x; 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // This is the right corner which a panel will be moved to. 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int right_x_to_move_to = 177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dragging_panel_bounds_.x() + dragging_panel_bounds_.width(); 178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Checks the panels to the left of the dragging panel. 180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t i = dragging_panel_index_; 181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t j = i + 1; 182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (; j < active_panels_.size(); ++j, ++i) { 183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Current panel will only be affected if the left corner of dragging 184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // panel goes beyond the middle position of the current panel. 185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (dragging_panel_x > active_panels_[j]->bounds().x() + 186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_[j]->bounds().width() / 2) 187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Moves current panel to the new position. 190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Rect bounds(active_panels_[j]->bounds()); 191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bounds.set_x(right_x_to_move_to - bounds.width()); 192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen right_x_to_move_to -= bounds.width() + kPanelsHorizontalSpacing; 193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_[j]->SetBounds(bounds); 194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Adjusts the index of current panel. 196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_[i] = active_panels_[j]; 197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Adjusts the position and index of dragging panel as the result of moving 200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // other affected panels. 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (j != dragging_panel_index_ + 1) { 202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen j--; 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dragging_panel_bounds_.set_x(right_x_to_move_to - 204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dragging_panel_bounds_.width()); 205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_[j] = dragging_panel; 206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dragging_panel_index_ = j; 207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::DragPositive(int delta_x) { 211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(delta_x > 0); 212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Panel* dragging_panel = active_panels_[dragging_panel_index_]; 214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // This is the right corner of the dragging panel. We use it to check against 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // all the panels on its right. 217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int dragging_panel_x = dragging_panel->bounds().x() + 218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dragging_panel->bounds().width() - 1 + delta_x; 219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // This is the left corner which a panel will be moved to. 221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int left_x_to_move_to = dragging_panel_bounds_.x(); 222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Checks the panels to the right of the dragging panel. 224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int i = static_cast<int>(dragging_panel_index_); 225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int j = i - 1; 226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (; j >= 0; --j, --i) { 227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Current panel will only be affected if the right corner of dragging 228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // panel goes beyond the middle position of the current panel. 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (dragging_panel_x < active_panels_[j]->bounds().x() + 230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_[j]->bounds().width() / 2) 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Moves current panel to the new position. 234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Rect bounds(active_panels_[j]->bounds()); 235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bounds.set_x(left_x_to_move_to); 236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen left_x_to_move_to += bounds.width() + kPanelsHorizontalSpacing; 237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_[j]->SetBounds(bounds); 238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Adjusts the index of current panel. 240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_[i] = active_panels_[j]; 241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Adjusts the position and index of dragging panel as the result of moving 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // other affected panels. 245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (j != static_cast<int>(dragging_panel_index_) - 1) { 246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen j++; 247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dragging_panel_bounds_.set_x(left_x_to_move_to); 248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_[j] = dragging_panel; 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dragging_panel_index_ = j; 250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::EndDragging(bool cancelled) { 254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(dragging_panel_index_ != kInvalidPanelIndex); 255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (cancelled) { 257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Drag(dragging_panel_original_x_ - 258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_[dragging_panel_index_]->bounds().x()); 259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_[dragging_panel_index_]->SetBounds(dragging_panel_bounds_); 261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dragging_panel_index_ = kInvalidPanelIndex; 264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DelayedRemove(); 266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::Rearrange(ActivePanels::iterator iter_to_start) { 269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (iter_to_start == active_panels_.end()) 270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (ActivePanels::iterator iter = iter_to_start; 273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter != active_panels_.end(); ++iter) { 274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Rect new_bounds((*iter)->bounds()); 275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ComputeBoundsForNextPanel(&new_bounds, false); 276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (new_bounds != (*iter)->bounds()) 277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (*iter)->SetBounds(new_bounds); 278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool PanelManager::ComputeBoundsForNextPanel(gfx::Rect* bounds, 282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool allow_size_change) { 283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int width = bounds->width(); 284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int height = bounds->height(); 285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Update the width and/or height to fit into our constraint. 287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (allow_size_change) { 288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (width == 0 && height == 0) { 289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen width = kPanelDefaultWidthPixels; 290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen height = kPanelDefaultHeightPixels; 291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (width < kPanelMinWidthPixels) 294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen width = kPanelMinWidthPixels; 295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen else if (width > max_width_) 296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen width = max_width_; 297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (height < kPanelMinHeightPixels) 299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen height = kPanelMinHeightPixels; 300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen else if (height > max_height_) 301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen height = max_height_; 302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int x = current_x_ - width; 305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int y = bottom_edge_y_ - height; 306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (x < min_x_) 308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen current_x_ -= width + kPanelsHorizontalSpacing; 311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bounds->SetRect(x, y, width, height); 313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::MinimizeAll() { 317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (ActivePanels::const_iterator iter = active_panels_.begin(); 318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter != active_panels_.end(); ++iter) { 319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (*iter)->Minimize(); 320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::RestoreAll() { 324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (ActivePanels::const_iterator iter = active_panels_.begin(); 325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter != active_panels_.end(); ++iter) { 326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (*iter)->Restore(); 327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PanelManager::RemoveAllActive() { 331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // This should not be called when we're in the process of dragging. 332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(dragging_panel_index_ == kInvalidPanelIndex); 333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Start from the bottom to avoid reshuffling. 335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (int i = static_cast<int>(active_panels_.size()) -1; i >= 0; --i) 336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen active_panels_[i]->Close(); 337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProcessPending(); 339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool PanelManager::AreAllMinimized() const { 342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (ActivePanels::const_iterator iter = active_panels_.begin(); 343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter != active_panels_.end(); ++iter) { 344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!(*iter)->minimized()) 345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 349