stacked_panel_collection.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/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" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/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()) 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 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) 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void StackedPanelCollection::PanelBoundsBatchUpdateCompleted() { 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!secondary_stack_window_ || panels_.empty()) 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (top_panel()->in_preview_mode() != bottom_panel()->in_preview_mode() || 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->IsAnimatingPanelBounds() || 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_->IsAnimatingPanelBounds()) 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Move all panels from secondary stack window to primary stack window. 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->MergeWith(secondary_stack_window_); 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_->Close(); 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_ = NULL; 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect StackedPanelCollection::GetEnclosingBounds() const { 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect enclosing_bounds = top_panel()->GetBounds(); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enclosing_bounds.set_height( 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bottom_panel()->GetBounds().bottom() - enclosing_bounds.y()); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return enclosing_bounds; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int StackedPanelCollection::MinimizePanelsForSpace(int needed_space) { 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int available_space = GetCurrentAvailableBottomSpace(); 176a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 177a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Only the most recently active panel might be active. 178a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) Panel* active_panel = NULL; 179a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!most_recently_active_panels_.empty()) { 180a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) Panel* most_recently_active_panel = most_recently_active_panels_.front(); 181a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (most_recently_active_panel->IsActive()) 182a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) active_panel = most_recently_active_panel; 183a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 184a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_reverse_iterator iter = 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) most_recently_active_panels_.rbegin(); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != most_recently_active_panels_.rend() && 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) available_space < needed_space; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++iter) { 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* current_panel = *iter; 191a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (current_panel != active_panel && !IsPanelMinimized(current_panel)) { 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) available_space += 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_panel->GetBounds().height() - panel::kTitlebarHeight; 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MinimizePanel(current_panel); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return available_space; 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::AddPanel(Panel* panel, 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PositioningMask positioning_mask) { 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(this, panel->collection()); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->set_collection(this); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* adjacent_panel = NULL; 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (positioning_mask & PanelCollection::TOP_POSITION) { 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) adjacent_panel = top_panel(); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panels_.push_front(panel); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // To fit the new panel within the working area, collapse unfocused panels 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in the least recent active order until there is enough space. 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (positioning_mask & PanelCollection::COLLAPSE_TO_FIT) { 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int needed_space = panel->GetBounds().height(); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int available_space = MinimizePanelsForSpace(needed_space); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(available_space >= needed_space); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) adjacent_panel = bottom_panel(); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panels_.push_back(panel); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel->IsActive()) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) most_recently_active_panels_.push_front(panel); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) most_recently_active_panels_.push_back(panel); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (adjacent_panel) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePanelCornerStyle(adjacent_panel); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The secondary stack window should be used when one of the following occurs: 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 1) Some panels but not all panels are being dragged. This is because 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // those panels being dragged might not be fully aligned with other panels 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // not being dragged. 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 2) The newly added panel is not fully aligned with the existing panel, in 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // terms of both x and width. 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NativePanelStackWindow* stack_window; 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (top_panel()->in_preview_mode() == bottom_panel()->in_preview_mode() && 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) top_panel()->GetBounds().x() == bottom_panel()->GetBounds().x() && 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) top_panel()->GetBounds().width() == bottom_panel()->GetBounds().width()) { 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!primary_stack_window_) 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_ = NativePanelStackWindow::Create(this); 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stack_window = primary_stack_window_; 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!secondary_stack_window_) 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_ = NativePanelStackWindow::Create(this); 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stack_window = secondary_stack_window_; 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stack_window->AddPanel(panel); 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((positioning_mask & NO_LAYOUT_REFRESH) == 0) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RefreshLayout(); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::RemovePanel(Panel* panel, RemovalReason reason) { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_top = panel == top_panel(); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_bottom = panel == bottom_panel(); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the top panel is being closed, all panels below it should move up. To 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // do this, the top y position of top panel needs to be tracked first. 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool top_panel_closed = false; 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Point top_origin; 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int top_width = 0; 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (reason == PanelCollection::PANEL_CLOSED && is_top) { 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) top_panel_closed = true; 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) top_origin = panel->GetBounds().origin(); 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) top_width = panel->GetBounds().width(); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->set_collection(NULL); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panels_.remove(panel); 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) most_recently_active_panels_.remove(panel); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_top) { 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* new_top_panel = top_panel(); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (new_top_panel) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePanelCornerStyle(new_top_panel); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (is_bottom) { 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* new_bottom_panel = bottom_panel(); 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (new_bottom_panel) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePanelCornerStyle(new_bottom_panel); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If an active panel is being closed, try to focus the next recently active 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // panel in the stack. 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (reason == PanelCollection::PANEL_CLOSED && 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->IsActive() && 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !most_recently_active_panels_.empty()) { 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) most_recently_active_panels_.front()->Activate(); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If the top panel is closed, move up all other panels to stay at the same 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // y position as the top panel being closed. 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (top_panel_closed) 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RefreshLayoutWithTopPanelStartingAt(top_origin, top_width); 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else if (reason == PanelCollection::PANEL_CLOSED) 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RefreshLayout(); 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Remove the panel from the corresponding stack window. 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetStackWindowForPanel(panel)->RemovePanel(panel); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Close the secondary stack window if no panel is is shown inside it. 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Note that we do not need to do this for primary stack window since the 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // whole stack will be gone when only one panel is left. 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (secondary_stack_window_ && secondary_stack_window_->IsEmpty()) { 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_->Close(); 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_ = NULL; 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::CloseAll() { 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make a copy as closing panels can modify the iterator. 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panels panels_copy = panels_; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = panels_copy.begin(); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != panels_copy.end(); ++iter) 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*iter)->Close(); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (primary_stack_window_) { 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->Close(); 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_ = NULL; 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (secondary_stack_window_) { 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_->Close(); 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_ = NULL; 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnPanelAttentionStateChanged(Panel* panel) { 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((panel->attention_mode() & Panel::USE_SYSTEM_ATTENTION) != 0) 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->DrawSystemAttention(panel->IsDrawingAttention()); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnPanelTitlebarClicked( 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel, panel::ClickModifier modifier) { 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool expanded = panel->expansion_state() == Panel::EXPANDED; 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (modifier == panel::APPLY_TO_ALL) { 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (expanded) 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MinimizeAll(); 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RestoreAll(panel); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (expanded) 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MinimizePanel(panel); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RestorePanel(panel); 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::ResizePanelWindow( 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel, 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Size& preferred_window_size) { 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::ActivatePanel(Panel* panel) { 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure the panel is expanded when activated so the user input 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // does not go into a collapsed window. 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel->IsMinimized()) 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->SetExpansionState(Panel::EXPANDED); 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::MinimizePanel(Panel* panel) { 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->SetExpansionState(Panel::TITLE_ONLY); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::RestorePanel(Panel* panel) { 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure that the panel could fit within the work area after it is expanded. 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // First, try to collapse the unfocused panel in the least recent active 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // order in order to get enough space. 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int needed_space = panel->full_size().height() - panel->TitleOnlyHeight(); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int available_space = MinimizePanelsForSpace(needed_space); 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there is still not enough space, try to move up the stack. 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int space_beyond_available = needed_space - available_space; 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (space_beyond_available > 0) { 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int top_available_space = GetCurrentAvailableTopSpace(); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int move_delta = (space_beyond_available > top_available_space) ? 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) top_available_space : space_beyond_available; 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = panels_.begin(); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != panels_.end(); iter++) { 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* current_panel = *iter; 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect bounds = current_panel->GetBounds(); 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.set_y(bounds.y() - move_delta); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_panel->SetPanelBounds(bounds); 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) available_space += move_delta; 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there is still not enough space, shrink the restored height to make it 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // fit at the last resort. Note that the restored height cannot be shrunk less 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // than the minimum panel height. If this is the case, we will just let it 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expand beyond the screen boundary. 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) space_beyond_available = needed_space - available_space; 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (space_beyond_available > 0) { 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Size full_size = panel->full_size(); 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int reduced_height = full_size.height() - space_beyond_available; 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (reduced_height < panel::kPanelMinHeight) 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reduced_height = panel::kPanelMinHeight; 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) full_size.set_height(reduced_height); 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->set_full_size(full_size); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->SetExpansionState(Panel::EXPANDED); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::MinimizeAll() { 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set minimizing_all_ to prevent deactivation of each panel when it 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is minimized. See comments in OnPanelExpansionStateChanged. 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<bool> pin(&minimizing_all_, true); 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* minimized_active_panel = NULL; 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = panels_.begin(); 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != panels_.end(); ++iter) { 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*iter)->IsActive()) 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) minimized_active_panel = *iter; 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MinimizePanel(*iter); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // When a single panel is minimized, it is deactivated to ensure that 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // a minimized panel does not have focus. However, when minimizing all, 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the deactivation is only done once after all panels are minimized, 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // rather than per minimized panel, both for efficiency and to avoid 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // temporary activations of random not-yet-minimized panels. 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (minimized_active_panel) { 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) minimized_active_panel->Deactivate(); 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Layout will be refreshed in response to (de)activation notification. 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::RestoreAll(Panel* panel_clicked) { 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Expand the panel being clicked first. This is to make sure at least one 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // panel that is clicked by the user will be expanded. 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RestorePanel(panel_clicked); 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Try to expand all other panels starting from the most recently active 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // panel. 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = most_recently_active_panels_.begin(); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != most_recently_active_panels_.end(); ++iter) { 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the stack already extends to both top and bottom of the work area, 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // stop now since we cannot fit any more expanded panels. 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (GetCurrentAvailableTopSpace() == 0 && 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetCurrentAvailableBottomSpace() == 0) { 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel = *iter; 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel != panel_clicked) 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RestorePanel(panel); 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnMinimizeButtonClicked( 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel, panel::ClickModifier modifier) { 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The minimize button is only present in the top panel. 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(top_panel(), panel); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->Minimize(); 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnRestoreButtonClicked( 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel, panel::ClickModifier modifier) { 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool StackedPanelCollection::CanShowMinimizeButton(const Panel* panel) const { 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only the top panel in the stack shows the minimize button. 464a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return PanelManager::CanUseSystemMinimize() && panel == top_panel(); 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool StackedPanelCollection::CanShowRestoreButton(const Panel* panel) const { 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool StackedPanelCollection::IsPanelMinimized(const Panel* panel) const { 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return panel->expansion_state() != Panel::EXPANDED; 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 47590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool StackedPanelCollection::UsesAlwaysOnTopPanels() const { 47690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 47790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 47890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::SavePanelPlacement(Panel* panel) { 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!saved_panel_placement_.panel); 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.panel = panel; 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (top_panel() != panel) 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.top_panel = top_panel(); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.position = panel->GetBounds().origin(); 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.top_panel = top_panel() != panel ? top_panel() : NULL; 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::RestorePanelToSavedPlacement() { 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(saved_panel_placement_.panel); 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (saved_panel_placement_.top_panel) { 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Restore the top panel if it has been moved out of the stack. This could 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // happen when there're 2 panels in the stack and the bottom panel is being 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dragged out of the stack and thus cause both panels become detached. 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (saved_panel_placement_.top_panel->stack() != this) { 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(PanelCollection::DETACHED, 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.top_panel->collection()->type()); 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) panel_manager_->MovePanelToCollection( 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) saved_panel_placement_.top_panel, 503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<PanelCollection::PositioningMask>( 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PanelCollection::TOP_POSITION | 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PanelCollection::NO_LAYOUT_REFRESH)); 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RefreshLayout(); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Restore the position when the top panel is being dragged. 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(top_panel(), saved_panel_placement_.panel); 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RefreshLayoutWithTopPanelStartingAt(saved_panel_placement_.position, 513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) top_panel()->GetBounds().width()); 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DiscardSavedPanelPlacement(); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::DiscardSavedPanelPlacement() { 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(saved_panel_placement_.panel); 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.panel = NULL; 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) saved_panel_placement_.top_panel = NULL; 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)panel::Resizability StackedPanelCollection::GetPanelResizability( 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Panel* panel) const { 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The panel in the stack can be resized by the following rules: 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // * If collapsed, it can only be resized by its left or right edge. 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // * Otherwise, it can be resized by its left or right edge plus: 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // % top edge and corners, if it is at the top; 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // % bottom edge, if it is not at the bottom. 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // % bottom edge and corners, if it is at the bottom. 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::Resizability resizability = static_cast<panel::Resizability>( 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::RESIZABLE_LEFT | panel::RESIZABLE_RIGHT); 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel->IsMinimized()) 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return resizability; 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel == top_panel()) { 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resizability = static_cast<panel::Resizability>(resizability | 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::RESIZABLE_TOP | panel::RESIZABLE_TOP_LEFT | 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::RESIZABLE_TOP_RIGHT); 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel == bottom_panel()) { 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resizability = static_cast<panel::Resizability>(resizability | 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::RESIZABLE_BOTTOM | panel::RESIZABLE_BOTTOM_LEFT | 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::RESIZABLE_BOTTOM_RIGHT); 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resizability = static_cast<panel::Resizability>(resizability | 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::RESIZABLE_BOTTOM); 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return resizability; 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnPanelResizedByMouse( 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* resized_panel, const gfx::Rect& new_bounds) { 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resized_panel->set_full_size(new_bounds.size()); 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!secondary_stack_window_); 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->BeginBatchUpdatePanelBounds(false); 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The delta x and width can be computed from the difference between 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the panel being resized and any other panel. 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* other_panel = resized_panel == top_panel() ? bottom_panel() 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : top_panel(); 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect other_bounds = other_panel->GetBounds(); 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int delta_x = new_bounds.x() - other_bounds.x(); 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int delta_width = new_bounds.width() - other_bounds.width(); 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect previous_bounds; 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool resized_panel_found = false; 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool panel_below_resized_panel_updated = false; 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = panels_.begin(); 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != panels_.end(); iter++) { 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel = *iter; 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel == resized_panel) { 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |new_bounds| should be used since the panel bounds have not been 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // updated yet. 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) previous_bounds = new_bounds; 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resized_panel_found = true; 579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->AddPanelBoundsForBatchUpdate(panel, new_bounds); 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect bounds = panel->GetBounds(); 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.set_x(bounds.x() + delta_x); 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.set_width(bounds.width() + delta_width); 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the panel below the panel being resized is expanded, update its 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // height to offset the height change of the panel being resized. 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For example, the stack has P1 and P2 (from top to bottom). P1's height 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is 100 and P2's height is 120. If P1's bottom increases by 10, P2's 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // height needs to shrink by 10. 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (resized_panel_found) { 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!panel_below_resized_panel_updated && !panel->IsMinimized()) { 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int old_bottom = bounds.bottom(); 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.set_y(previous_bounds.bottom()); 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.set_height(old_bottom - bounds.y()); 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bounds.set_y(previous_bounds.bottom()); 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel_below_resized_panel_updated = true; 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!panel->IsMinimized()) 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->set_full_size(bounds.size()); 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->AddPanelBoundsForBatchUpdate(panel, bounds); 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) previous_bounds = bounds; 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_stack_window_->EndBatchUpdatePanelBounds(); 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool StackedPanelCollection::HasPanel(Panel* panel) const { 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::find(panels_.begin(), panels_.end(), panel) != panels_.end(); 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::UpdatePanelOnCollectionChange(Panel* panel) { 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->set_attention_mode( 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<Panel::AttentionMode>(Panel::USE_PANEL_ATTENTION | 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel::USE_SYSTEM_ATTENTION)); 621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) panel->ShowShadow(false); 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->EnableResizeByMouse(true); 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->UpdateMinimizeRestoreButtonVisibility(); 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePanelCornerStyle(panel); 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnPanelExpansionStateChanged(Panel* panel) { 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(Panel::MINIMIZED, panel->expansion_state()); 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure minimized panel does not get the focus. If minimizing all, 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the active panel will be deactivated once when all panels are minimized 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // rather than per minimized panel. 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panel->expansion_state() != Panel::EXPANDED && !minimizing_all_ && 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->IsActive()) { 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->Deactivate(); 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The bounds change per expansion state will be done in RefreshLayout. 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RefreshLayout(); 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::OnPanelActiveStateChanged(Panel* panel) { 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!panel->IsActive()) 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 646a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Move the panel to the front if not yet. 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panels::iterator iter = std::find(most_recently_active_panels_.begin(), 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) most_recently_active_panels_.end(), panel); 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(iter != most_recently_active_panels_.end()); 650a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (iter != most_recently_active_panels_.begin()) { 651a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) most_recently_active_panels_.erase(iter); 652a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) most_recently_active_panels_.push_front(panel); 653a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 655a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) GetStackWindowForPanel(panel)->OnPanelActivated(panel); 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Rect StackedPanelCollection::GetInitialPanelBounds( 659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const gfx::Rect& requested_bounds) const { 660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!panels_.empty()); 661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect bottom_panel_bounds = bottom_panel()->GetBounds(); 662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return gfx::Rect(bottom_panel_bounds.x(), 663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bottom_panel_bounds.bottom(), 664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bottom_panel_bounds.width(), 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) requested_bounds.height()); 666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Panel* StackedPanelCollection::GetPanelAbove(Panel* panel) const { 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(panel); 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panels_.size() < 2) 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panels::const_iterator iter = panels_.begin(); 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* above_panel = *iter; 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (; iter != panels_.end(); ++iter) { 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (*iter == panel) 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return above_panel; 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) above_panel = *iter; 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Panel* StackedPanelCollection::GetPanelBelow(Panel* panel) const { 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(panel); 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panels_.size() < 2) 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panels::const_iterator iter = 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::find(panels_.begin(), panels_.end(), panel); 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter == panels_.end()) 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++iter; 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return iter == panels_.end() ? NULL : *iter; 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::MoveAllDraggingPanelsInstantly( 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Vector2d& delta_origin) { 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = panels_.begin(); 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != panels_.end(); iter++) { 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel = *iter; 701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (panel->in_preview_mode()) { 702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetStackWindowForPanel(panel)->MovePanelsBy(delta_origin); 703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool StackedPanelCollection::IsMinimized() const { 709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return primary_stack_window_->IsMinimized(); 710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool StackedPanelCollection::IsAnimatingPanelBounds(Panel* panel) const { 713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return GetStackWindowForPanel(panel)->IsAnimatingPanelBounds(); 714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StackedPanelCollection::UpdatePanelCornerStyle(Panel* panel) { 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel::CornerStyle corner_style; 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool at_top = panel == top_panel(); 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool at_bottom = panel == bottom_panel(); 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (at_top && at_bottom) 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) corner_style = panel::ALL_ROUNDED; 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (at_top) 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) corner_style = panel::TOP_ROUNDED; 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (at_bottom) 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) corner_style = panel::BOTTOM_ROUNDED; 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) corner_style = panel::NOT_ROUNDED; 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) panel->SetWindowCornerStyle(corner_style); 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect StackedPanelCollection::GetWorkArea() const { 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panels_.empty()) 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return panel_manager_->display_settings_provider()->GetPrimaryWorkArea(); 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return panel_manager_->display_settings_provider()->GetWorkAreaMatching( 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetEnclosingBounds()); 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int StackedPanelCollection::GetCurrentAvailableTopSpace() const { 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect work_area = GetWorkArea(); 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panels_.empty()) 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return work_area.height(); 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int available_space = top_panel()->GetBounds().y() - work_area.y(); 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (available_space < 0) 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) available_space = 0; 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return available_space; 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int StackedPanelCollection::GetCurrentAvailableBottomSpace() const { 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect work_area = GetWorkArea(); 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (panels_.empty()) 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return work_area.height(); 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int available_space = work_area.bottom() - 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bottom_panel()->GetBounds().bottom(); 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::GetMaximiumAvailableBottomSpace() 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 bottom = top_panel()->GetBounds().y(); 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Panels::const_iterator iter = panels_.begin(); 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != panels_.end(); iter++) { 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Panel* panel = *iter; 770a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Only the most recently active panel might be active. 771a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (iter == panels_.begin() && panel->IsActive()) 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bottom += panel->GetBounds().height(); 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bottom += panel::kTitlebarHeight; 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int available_space = work_area.bottom() - bottom; 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (available_space < 0) 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) available_space = 0; 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return available_space; 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)NativePanelStackWindow* StackedPanelCollection::GetStackWindowForPanel( 783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Panel* panel) const { 784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return secondary_stack_window_ && secondary_stack_window_->HasPanel(panel) ? 785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) secondary_stack_window_ : primary_stack_window_; 786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 787