stacked_panel_collection.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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/stacked_panel_collection.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/auto_reset.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/detached_panel_collection.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/display_settings_provider.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/ui/panels/native_panel_stack_window.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/panel.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/panel_constants.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/panel_manager.h" 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StackedPanelCollection::StackedPanelCollection(PanelManager* panel_manager) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : PanelCollection(PanelCollection::STACKED), 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel_manager_(panel_manager), 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_(NULL), 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_(NULL), 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) minimizing_all_(false) { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StackedPanelCollection::~StackedPanelCollection() { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(panels_.empty()); 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(most_recently_active_panels_.empty()); 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnDisplayChanged() { 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panels_.empty()) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect enclosing_bounds = GetEnclosingBounds(); 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect work_area = panel_manager_->display_settings_provider()-> 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetWorkAreaMatching(enclosing_bounds); 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the height of the whole stack is bigger than the height of the new work 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // area, try to reduce the stack height by collapsing panels. In rare case, 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // all panels are collapsed and there is still not enough space. We simply 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // let the stack go beyond the work area limit. 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (enclosing_bounds.height() > work_area.height()) { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int needed_space = enclosing_bounds.height() - work_area.height(); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MinimizePanelsForSpace(needed_space); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect top_bounds = top_panel()->GetBounds(); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int common_width = top_bounds.width(); 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (common_width > work_area.width()) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) common_width = work_area.width(); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int common_x = top_bounds.x(); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (common_x + common_width > work_area.right()) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) common_x = work_area.right() - common_width; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (common_x < work_area.x()) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) common_x = work_area.x(); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int total_height = bottom_panel()->GetBounds().bottom() - top_bounds.y(); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int start_y = top_bounds.y(); 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (start_y + total_height > work_area.bottom()) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_y = work_area.bottom() - total_height; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (start_y < work_area.y()) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_y = work_area.y(); 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RefreshLayoutWithTopPanelStartingAt( 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Point(common_x, start_y), common_width); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::RefreshLayout() { 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panels_.empty()) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect top_bounds = top_panel()->GetBounds(); 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RefreshLayoutWithTopPanelStartingAt(top_bounds.origin(), top_bounds.width()); 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StackedPanelCollection::RefreshLayoutWithTopPanelStartingAt( 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const gfx::Point& start_position, int common_width) { 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (panels_.empty()) 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If only one panel is left in the stack, we only need to check if it should 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // be moved to |start_y| position. 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (panels_.size() == 1) { 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Panel* panel = panels_.front(); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect bounds = panel->GetBounds(); 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (bounds.origin() != start_position) { 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bounds.set_origin(start_position); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) panel->SetPanelBounds(bounds); 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We do not update bounds for affected panels one by one. Instead, all 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // changes are bundled and performed synchronously. 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->BeginBatchUpdatePanelBounds(true); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (secondary_stack_window_) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_->BeginBatchUpdatePanelBounds(true); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int y = start_position.y(); 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int common_x = start_position.x(); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (Panels::const_iterator iter = panels_.begin(); 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) iter != panels_.end(); ++iter) { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel = *iter; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The visibility of minimize button might need to be updated due to that 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // top panel might change when a panel is being added or removed from 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the stack. 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->UpdateMinimizeRestoreButtonVisibility(); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't update the stacked panel that is in preview mode. 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect bounds = panel->GetBounds(); 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (panel->in_preview_mode()) { 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) y += bounds.height(); 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Update the restored size. 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Size full_size = panel->full_size(); 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) full_size.set_width(common_width); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) panel->set_full_size(full_size); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Recompute the bounds. 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bounds.SetRect( 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) common_x, 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) y, 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) common_width, 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) panel->expansion_state() == Panel::EXPANDED ? 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) panel->full_size().height() : panel->TitleOnlyHeight()); 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetStackWindowForPanel(panel)->AddPanelBoundsForBatchUpdate(panel, bounds); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) y += bounds.height(); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->EndBatchUpdatePanelBounds(); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (secondary_stack_window_) 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_->EndBatchUpdatePanelBounds(); 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 StackedPanelCollection::GetTitle() const { 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (panels_.empty()) 144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return base::string16(); 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Panel* panel = panels_.front(); 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const extensions::Extension* extension = panel->GetExtension(); 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return UTF8ToUTF16(extension && !extension->name().empty() ? 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension->name() : panel->app_name()); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)gfx::Image StackedPanelCollection::GetIcon() const { 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (panels_.empty()) 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return gfx::Image(); 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return panels_.front()->app_icon(); 156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StackedPanelCollection::PanelBoundsBatchUpdateCompleted() { 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!secondary_stack_window_ || panels_.empty()) 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (top_panel()->in_preview_mode() != bottom_panel()->in_preview_mode() || 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->IsAnimatingPanelBounds() || 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_->IsAnimatingPanelBounds()) 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Move all panels from secondary stack window to primary stack window. 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->MergeWith(secondary_stack_window_); 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_->Close(); 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_ = NULL; 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect StackedPanelCollection::GetEnclosingBounds() const { 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect enclosing_bounds = top_panel()->GetBounds(); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enclosing_bounds.set_height( 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bottom_panel()->GetBounds().bottom() - enclosing_bounds.y()); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return enclosing_bounds; 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int StackedPanelCollection::MinimizePanelsForSpace(int needed_space) { 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int available_space = GetCurrentAvailableBottomSpace(); 182a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 183a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Only the most recently active panel might be active. 184a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) Panel* active_panel = NULL; 185a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!most_recently_active_panels_.empty()) { 186a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) Panel* most_recently_active_panel = most_recently_active_panels_.front(); 187a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (most_recently_active_panel->IsActive()) 188a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) active_panel = most_recently_active_panel; 189a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 190a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_reverse_iterator iter = 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) most_recently_active_panels_.rbegin(); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != most_recently_active_panels_.rend() && 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) available_space < needed_space; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++iter) { 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* current_panel = *iter; 197a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (current_panel != active_panel && !IsPanelMinimized(current_panel)) { 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) available_space += 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_panel->GetBounds().height() - panel::kTitlebarHeight; 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MinimizePanel(current_panel); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return available_space; 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::AddPanel(Panel* panel, 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PositioningMask positioning_mask) { 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(this, panel->collection()); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->set_collection(this); 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* adjacent_panel = NULL; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (positioning_mask & PanelCollection::TOP_POSITION) { 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) adjacent_panel = top_panel(); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panels_.push_front(panel); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // To fit the new panel within the working area, collapse unfocused panels 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in the least recent active order until there is enough space. 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (positioning_mask & PanelCollection::COLLAPSE_TO_FIT) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int needed_space = panel->GetBounds().height(); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int available_space = MinimizePanelsForSpace(needed_space); 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(available_space >= needed_space); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) adjacent_panel = bottom_panel(); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panels_.push_back(panel); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel->IsActive()) 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) most_recently_active_panels_.push_front(panel); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) most_recently_active_panels_.push_back(panel); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (adjacent_panel) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePanelCornerStyle(adjacent_panel); 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The secondary stack window should be used when one of the following occurs: 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 1) Some panels but not all panels are being dragged. This is because 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // those panels being dragged might not be fully aligned with other panels 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // not being dragged. 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 2) The newly added panel is not fully aligned with the existing panel, in 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // terms of both x and width. 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NativePanelStackWindow* stack_window; 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (top_panel()->in_preview_mode() == bottom_panel()->in_preview_mode() && 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) top_panel()->GetBounds().x() == bottom_panel()->GetBounds().x() && 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) top_panel()->GetBounds().width() == bottom_panel()->GetBounds().width()) { 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!primary_stack_window_) 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_ = NativePanelStackWindow::Create(this); 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stack_window = primary_stack_window_; 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!secondary_stack_window_) 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_ = NativePanelStackWindow::Create(this); 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stack_window = secondary_stack_window_; 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stack_window->AddPanel(panel); 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((positioning_mask & NO_LAYOUT_REFRESH) == 0) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RefreshLayout(); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::RemovePanel(Panel* panel, RemovalReason reason) { 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_top = panel == top_panel(); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_bottom = panel == bottom_panel(); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the top panel is being closed, all panels below it should move up. To 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // do this, the top y position of top panel needs to be tracked first. 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool top_panel_closed = false; 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Point top_origin; 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int top_width = 0; 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (reason == PanelCollection::PANEL_CLOSED && is_top) { 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) top_panel_closed = true; 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) top_origin = panel->GetBounds().origin(); 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) top_width = panel->GetBounds().width(); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->set_collection(NULL); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panels_.remove(panel); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) most_recently_active_panels_.remove(panel); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_top) { 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* new_top_panel = top_panel(); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (new_top_panel) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePanelCornerStyle(new_top_panel); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (is_bottom) { 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* new_bottom_panel = bottom_panel(); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (new_bottom_panel) 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePanelCornerStyle(new_bottom_panel); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If an active panel is being closed, try to focus the next recently active 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // panel in the stack that is not minimized. 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (reason == PanelCollection::PANEL_CLOSED && 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->IsActive() && 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !most_recently_active_panels_.empty()) { 2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (Panels::const_iterator iter = most_recently_active_panels_.begin(); 2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) iter != most_recently_active_panels_.end(); ++iter) { 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Panel* other_panel = *iter; 2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!IsPanelMinimized(other_panel)) { 2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) other_panel->Activate(); 2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If the top panel is closed, move up all other panels to stay at the same 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // y position as the top panel being closed. 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (top_panel_closed) 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RefreshLayoutWithTopPanelStartingAt(top_origin, top_width); 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else if (reason == PanelCollection::PANEL_CLOSED) 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RefreshLayout(); 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Remove the panel from the corresponding stack window. 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetStackWindowForPanel(panel)->RemovePanel(panel); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Close the secondary stack window if no panel is is shown inside it. 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Note that we do not need to do this for primary stack window since the 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // whole stack will be gone when only one panel is left. 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (secondary_stack_window_ && secondary_stack_window_->IsEmpty()) { 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_->Close(); 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_ = NULL; 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::CloseAll() { 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make a copy as closing panels can modify the iterator. 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panels panels_copy = panels_; 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = panels_copy.begin(); 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != panels_copy.end(); ++iter) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*iter)->Close(); 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (primary_stack_window_) { 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->Close(); 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_ = NULL; 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (secondary_stack_window_) { 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_->Close(); 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_ = NULL; 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnPanelAttentionStateChanged(Panel* panel) { 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((panel->attention_mode() & Panel::USE_SYSTEM_ATTENTION) != 0) 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->DrawSystemAttention(panel->IsDrawingAttention()); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnPanelTitlebarClicked( 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel, panel::ClickModifier modifier) { 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool expanded = panel->expansion_state() == Panel::EXPANDED; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (modifier == panel::APPLY_TO_ALL) { 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (expanded) 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MinimizeAll(); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RestoreAll(panel); 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (expanded) 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MinimizePanel(panel); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RestorePanel(panel); 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::ResizePanelWindow( 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel, 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Size& preferred_window_size) { 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::ActivatePanel(Panel* panel) { 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure the panel is expanded when activated so the user input 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // does not go into a collapsed window. 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel->IsMinimized()) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->SetExpansionState(Panel::EXPANDED); 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::MinimizePanel(Panel* panel) { 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->SetExpansionState(Panel::TITLE_ONLY); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::RestorePanel(Panel* panel) { 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure that the panel could fit within the work area after it is expanded. 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // First, try to collapse the unfocused panel in the least recent active 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // order in order to get enough space. 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int needed_space = panel->full_size().height() - panel->TitleOnlyHeight(); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int available_space = MinimizePanelsForSpace(needed_space); 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there is still not enough space, try to move up the stack. 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int space_beyond_available = needed_space - available_space; 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (space_beyond_available > 0) { 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int top_available_space = GetCurrentAvailableTopSpace(); 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int move_delta = (space_beyond_available > top_available_space) ? 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) top_available_space : space_beyond_available; 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = panels_.begin(); 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != panels_.end(); iter++) { 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* current_panel = *iter; 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect bounds = current_panel->GetBounds(); 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.set_y(bounds.y() - move_delta); 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_panel->SetPanelBounds(bounds); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) available_space += move_delta; 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there is still not enough space, shrink the restored height to make it 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // fit at the last resort. Note that the restored height cannot be shrunk less 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // than the minimum panel height. If this is the case, we will just let it 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expand beyond the screen boundary. 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) space_beyond_available = needed_space - available_space; 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (space_beyond_available > 0) { 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size full_size = panel->full_size(); 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int reduced_height = full_size.height() - space_beyond_available; 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (reduced_height < panel::kPanelMinHeight) 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reduced_height = panel::kPanelMinHeight; 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) full_size.set_height(reduced_height); 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->set_full_size(full_size); 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->SetExpansionState(Panel::EXPANDED); 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::MinimizeAll() { 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set minimizing_all_ to prevent deactivation of each panel when it 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is minimized. See comments in OnPanelExpansionStateChanged. 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> pin(&minimizing_all_, true); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* minimized_active_panel = NULL; 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = panels_.begin(); 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != panels_.end(); ++iter) { 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->IsActive()) 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) minimized_active_panel = *iter; 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MinimizePanel(*iter); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // When a single panel is minimized, it is deactivated to ensure that 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // a minimized panel does not have focus. However, when minimizing all, 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the deactivation is only done once after all panels are minimized, 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // rather than per minimized panel, both for efficiency and to avoid 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // temporary activations of random not-yet-minimized panels. 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (minimized_active_panel) { 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) minimized_active_panel->Deactivate(); 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Layout will be refreshed in response to (de)activation notification. 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::RestoreAll(Panel* panel_clicked) { 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Expand the panel being clicked first. This is to make sure at least one 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // panel that is clicked by the user will be expanded. 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RestorePanel(panel_clicked); 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Try to expand all other panels starting from the most recently active 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // panel. 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = most_recently_active_panels_.begin(); 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != most_recently_active_panels_.end(); ++iter) { 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the stack already extends to both top and bottom of the work area, 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // stop now since we cannot fit any more expanded panels. 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (GetCurrentAvailableTopSpace() == 0 && 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetCurrentAvailableBottomSpace() == 0) { 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel = *iter; 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel != panel_clicked) 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RestorePanel(panel); 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnMinimizeButtonClicked( 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel, panel::ClickModifier modifier) { 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The minimize button is only present in the top panel. 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(top_panel(), panel); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->Minimize(); 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnRestoreButtonClicked( 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel, panel::ClickModifier modifier) { 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool StackedPanelCollection::CanShowMinimizeButton(const Panel* panel) const { 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only the top panel in the stack shows the minimize button. 477a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return PanelManager::CanUseSystemMinimize() && panel == top_panel(); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool StackedPanelCollection::CanShowRestoreButton(const Panel* panel) const { 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool StackedPanelCollection::IsPanelMinimized(const Panel* panel) const { 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return panel->expansion_state() != Panel::EXPANDED; 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 48890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool StackedPanelCollection::UsesAlwaysOnTopPanels() const { 48990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 49090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::SavePanelPlacement(Panel* panel) { 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!saved_panel_placement_.panel); 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.panel = panel; 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (top_panel() != panel) 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.top_panel = top_panel(); 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.position = panel->GetBounds().origin(); 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.top_panel = top_panel() != panel ? top_panel() : NULL; 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::RestorePanelToSavedPlacement() { 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(saved_panel_placement_.panel); 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (saved_panel_placement_.top_panel) { 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Restore the top panel if it has been moved out of the stack. This could 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // happen when there're 2 panels in the stack and the bottom panel is being 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dragged out of the stack and thus cause both panels become detached. 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (saved_panel_placement_.top_panel->stack() != this) { 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(PanelCollection::DETACHED, 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.top_panel->collection()->type()); 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) panel_manager_->MovePanelToCollection( 515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) saved_panel_placement_.top_panel, 516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, 517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<PanelCollection::PositioningMask>( 518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PanelCollection::TOP_POSITION | 519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PanelCollection::NO_LAYOUT_REFRESH)); 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RefreshLayout(); 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Restore the position when the top panel is being dragged. 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(top_panel(), saved_panel_placement_.panel); 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RefreshLayoutWithTopPanelStartingAt(saved_panel_placement_.position, 526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) top_panel()->GetBounds().width()); 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DiscardSavedPanelPlacement(); 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::DiscardSavedPanelPlacement() { 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(saved_panel_placement_.panel); 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.panel = NULL; 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.top_panel = NULL; 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)panel::Resizability StackedPanelCollection::GetPanelResizability( 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Panel* panel) const { 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The panel in the stack can be resized by the following rules: 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // * If collapsed, it can only be resized by its left or right edge. 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // * Otherwise, it can be resized by its left or right edge plus: 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // % top edge and corners, if it is at the top; 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // % bottom edge, if it is not at the bottom. 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // % bottom edge and corners, if it is at the bottom. 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::Resizability resizability = static_cast<panel::Resizability>( 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::RESIZABLE_LEFT | panel::RESIZABLE_RIGHT); 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel->IsMinimized()) 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return resizability; 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel == top_panel()) { 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resizability = static_cast<panel::Resizability>(resizability | 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::RESIZABLE_TOP | panel::RESIZABLE_TOP_LEFT | 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::RESIZABLE_TOP_RIGHT); 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel == bottom_panel()) { 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resizability = static_cast<panel::Resizability>(resizability | 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::RESIZABLE_BOTTOM | panel::RESIZABLE_BOTTOM_LEFT | 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::RESIZABLE_BOTTOM_RIGHT); 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resizability = static_cast<panel::Resizability>(resizability | 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::RESIZABLE_BOTTOM); 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return resizability; 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnPanelResizedByMouse( 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* resized_panel, const gfx::Rect& new_bounds) { 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resized_panel->set_full_size(new_bounds.size()); 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!secondary_stack_window_); 571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->BeginBatchUpdatePanelBounds(false); 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The delta x and width can be computed from the difference between 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the panel being resized and any other panel. 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* other_panel = resized_panel == top_panel() ? bottom_panel() 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : top_panel(); 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect other_bounds = other_panel->GetBounds(); 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int delta_x = new_bounds.x() - other_bounds.x(); 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int delta_width = new_bounds.width() - other_bounds.width(); 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect previous_bounds; 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool resized_panel_found = false; 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool panel_below_resized_panel_updated = false; 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = panels_.begin(); 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != panels_.end(); iter++) { 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel = *iter; 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel == resized_panel) { 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |new_bounds| should be used since the panel bounds have not been 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // updated yet. 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) previous_bounds = new_bounds; 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resized_panel_found = true; 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->AddPanelBoundsForBatchUpdate(panel, new_bounds); 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect bounds = panel->GetBounds(); 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.set_x(bounds.x() + delta_x); 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.set_width(bounds.width() + delta_width); 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the panel below the panel being resized is expanded, update its 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // height to offset the height change of the panel being resized. 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For example, the stack has P1 and P2 (from top to bottom). P1's height 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is 100 and P2's height is 120. If P1's bottom increases by 10, P2's 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // height needs to shrink by 10. 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (resized_panel_found) { 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!panel_below_resized_panel_updated && !panel->IsMinimized()) { 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int old_bottom = bounds.bottom(); 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.set_y(previous_bounds.bottom()); 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.set_height(old_bottom - bounds.y()); 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.set_y(previous_bounds.bottom()); 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel_below_resized_panel_updated = true; 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!panel->IsMinimized()) 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->set_full_size(bounds.size()); 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->AddPanelBoundsForBatchUpdate(panel, bounds); 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) previous_bounds = bounds; 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->EndBatchUpdatePanelBounds(); 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool StackedPanelCollection::HasPanel(Panel* panel) const { 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::find(panels_.begin(), panels_.end(), panel) != panels_.end(); 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::UpdatePanelOnCollectionChange(Panel* panel) { 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->set_attention_mode( 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<Panel::AttentionMode>(Panel::USE_PANEL_ATTENTION | 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel::USE_SYSTEM_ATTENTION)); 634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) panel->ShowShadow(false); 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->UpdateMinimizeRestoreButtonVisibility(); 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePanelCornerStyle(panel); 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnPanelExpansionStateChanged(Panel* panel) { 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(Panel::MINIMIZED, panel->expansion_state()); 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure minimized panel does not get the focus. If minimizing all, 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the active panel will be deactivated once when all panels are minimized 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // rather than per minimized panel. 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel->expansion_state() != Panel::EXPANDED && !minimizing_all_ && 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->IsActive()) { 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->Deactivate(); 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The bounds change per expansion state will be done in RefreshLayout. 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RefreshLayout(); 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnPanelActiveStateChanged(Panel* panel) { 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!panel->IsActive()) 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 658a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Move the panel to the front if not yet. 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panels::iterator iter = std::find(most_recently_active_panels_.begin(), 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) most_recently_active_panels_.end(), panel); 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(iter != most_recently_active_panels_.end()); 662a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (iter != most_recently_active_panels_.begin()) { 663a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) most_recently_active_panels_.erase(iter); 664a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) most_recently_active_panels_.push_front(panel); 665a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 667a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) GetStackWindowForPanel(panel)->OnPanelActivated(panel); 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Rect StackedPanelCollection::GetInitialPanelBounds( 671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const gfx::Rect& requested_bounds) const { 672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!panels_.empty()); 673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect bottom_panel_bounds = bottom_panel()->GetBounds(); 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return gfx::Rect(bottom_panel_bounds.x(), 675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bottom_panel_bounds.bottom(), 676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bottom_panel_bounds.width(), 677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) requested_bounds.height()); 678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Panel* StackedPanelCollection::GetPanelAbove(Panel* panel) const { 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(panel); 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panels_.size() < 2) 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panels::const_iterator iter = panels_.begin(); 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* above_panel = *iter; 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (; iter != panels_.end(); ++iter) { 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (*iter == panel) 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return above_panel; 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) above_panel = *iter; 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Panel* StackedPanelCollection::GetPanelBelow(Panel* panel) const { 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(panel); 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panels_.size() < 2) 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panels::const_iterator iter = 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::find(panels_.begin(), panels_.end(), panel); 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter == panels_.end()) 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++iter; 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return iter == panels_.end() ? NULL : *iter; 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::MoveAllDraggingPanelsInstantly( 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Vector2d& delta_origin) { 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = panels_.begin(); 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != panels_.end(); iter++) { 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel = *iter; 713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (panel->in_preview_mode()) { 714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetStackWindowForPanel(panel)->MovePanelsBy(delta_origin); 715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool StackedPanelCollection::IsMinimized() const { 721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return primary_stack_window_->IsMinimized(); 722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool StackedPanelCollection::IsAnimatingPanelBounds(Panel* panel) const { 725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return GetStackWindowForPanel(panel)->IsAnimatingPanelBounds(); 726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::UpdatePanelCornerStyle(Panel* panel) { 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::CornerStyle corner_style; 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool at_top = panel == top_panel(); 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool at_bottom = panel == bottom_panel(); 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (at_top && at_bottom) 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) corner_style = panel::ALL_ROUNDED; 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (at_top) 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) corner_style = panel::TOP_ROUNDED; 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (at_bottom) 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) corner_style = panel::BOTTOM_ROUNDED; 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) corner_style = panel::NOT_ROUNDED; 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->SetWindowCornerStyle(corner_style); 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect StackedPanelCollection::GetWorkArea() const { 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panels_.empty()) 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return panel_manager_->display_settings_provider()->GetPrimaryWorkArea(); 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return panel_manager_->display_settings_provider()->GetWorkAreaMatching( 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetEnclosingBounds()); 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int StackedPanelCollection::GetCurrentAvailableTopSpace() const { 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect work_area = GetWorkArea(); 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panels_.empty()) 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return work_area.height(); 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int available_space = top_panel()->GetBounds().y() - work_area.y(); 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (available_space < 0) 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) available_space = 0; 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return available_space; 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int StackedPanelCollection::GetCurrentAvailableBottomSpace() const { 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect work_area = GetWorkArea(); 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panels_.empty()) 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return work_area.height(); 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int available_space = work_area.bottom() - 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bottom_panel()->GetBounds().bottom(); 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (available_space < 0) 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) available_space = 0; 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return available_space; 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int StackedPanelCollection::GetMaximiumAvailableBottomSpace() const { 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect work_area = GetWorkArea(); 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panels_.empty()) 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return work_area.height(); 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bottom = top_panel()->GetBounds().y(); 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = panels_.begin(); 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != panels_.end(); iter++) { 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel = *iter; 782a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Only the most recently active panel might be active. 783a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (iter == panels_.begin() && panel->IsActive()) 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bottom += panel->GetBounds().height(); 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bottom += panel::kTitlebarHeight; 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int available_space = work_area.bottom() - bottom; 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (available_space < 0) 7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) available_space = 0; 7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return available_space; 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)NativePanelStackWindow* StackedPanelCollection::GetStackWindowForPanel( 795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Panel* panel) const { 796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return secondary_stack_window_ && secondary_stack_window_->HasPanel(panel) ? 797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_ : primary_stack_window_; 798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 799