| Index: chrome/browser/ui/panels/docked_panel_strip.cc
|
| diff --git a/chrome/browser/ui/panels/docked_panel_strip.cc b/chrome/browser/ui/panels/docked_panel_strip.cc
|
| index d4cd227cac19fd76788d5eb3f63be9239b8b3f14..ef07bf5ddad82f6daf6168f5d1a729e78ebdf667 100644
|
| --- a/chrome/browser/ui/panels/docked_panel_strip.cc
|
| +++ b/chrome/browser/ui/panels/docked_panel_strip.cc
|
| @@ -11,7 +11,6 @@
|
| #include "base/logging.h"
|
| #include "base/message_loop.h"
|
| #include "chrome/browser/ui/browser.h"
|
| -#include "chrome/browser/ui/panels/overflow_panel_strip.h"
|
| #include "chrome/browser/ui/panels/panel_manager.h"
|
| #include "chrome/browser/ui/panels/panel_mouse_watcher.h"
|
| #include "chrome/common/chrome_notification_types.h"
|
| @@ -59,7 +58,6 @@ DockedPanelStrip::DockedPanelStrip(PanelManager* panel_manager)
|
| panel_manager_(panel_manager),
|
| minimized_panel_count_(0),
|
| are_titlebars_up_(false),
|
| - disable_layout_refresh_(false),
|
| delayed_titlebar_action_(NO_ACTION),
|
| titlebar_action_factory_(this) {
|
| dragging_panel_current_iterator_ = dragging_panel_original_iterator_ =
|
| @@ -86,9 +84,10 @@ void DockedPanelStrip::SetDisplayArea(const gfx::Rect& display_area) {
|
| }
|
|
|
| void DockedPanelStrip::AddPanel(Panel* panel) {
|
| - DCHECK_EQ(this, panel->panel_strip());
|
| + DCHECK_NE(this, panel->panel_strip());
|
| + panel->set_panel_strip(this);
|
|
|
| - // Always update limits, even for exiting panels, in case the maximums changed
|
| + // Always update limits, even on existing panels, in case the limits changed
|
| // while panel was out of the strip.
|
| int max_panel_width = GetMaxPanelWidth();
|
| int max_panel_height = GetMaxPanelHeight();
|
| @@ -100,16 +99,7 @@ void DockedPanelStrip::AddPanel(Panel* panel) {
|
| int width = restored_size.width();
|
|
|
| if (panel->initialized()) {
|
| - // Bump panels in the strip to make room for this panel.
|
| - // Prevent layout refresh when panel is removed from this strip.
|
| - disable_layout_refresh_ = true;
|
| - PanelStrip* overflow_strip = panel_manager_->overflow_strip();
|
| - int x;
|
| - while ((x = GetRightMostAvailablePosition() - width) < display_area_.x()) {
|
| - DCHECK(!panels_.empty());
|
| - panels_.back()->MoveToStrip(overflow_strip);
|
| - }
|
| - disable_layout_refresh_ = false;
|
| + int x = FitPanelWithWidth(width);
|
|
|
| Panel::ExpansionState expansion_state_to_restore;
|
| if (panel->expansion_state() == Panel::EXPANDED) {
|
| @@ -124,7 +114,6 @@ void DockedPanelStrip::AddPanel(Panel* panel) {
|
| }
|
| IncrementMinimizedPanels();
|
| }
|
| -
|
| int y =
|
| GetBottomPositionForExpansionState(expansion_state_to_restore) - height;
|
| panel->SetPanelBounds(gfx::Rect(x, y, width, height));
|
| @@ -203,45 +192,43 @@ int DockedPanelStrip::GetRightMostAvailablePosition() const {
|
| (panels_.back()->GetBounds().x() - kPanelsHorizontalSpacing);
|
| }
|
|
|
| -bool DockedPanelStrip::RemovePanel(Panel* panel) {
|
| - if (panel->has_temporary_layout()) {
|
| - panels_in_temporary_layout_.erase(panel);
|
| - return true;
|
| - }
|
| -
|
| - Panels::iterator iter = find(panels_.begin(), panels_.end(), panel);
|
| - if (iter == panels_.end())
|
| - return false;
|
| +void DockedPanelStrip::RemovePanel(Panel* panel) {
|
| + DCHECK_EQ(this, panel->panel_strip());
|
| + panel->set_panel_strip(NULL);
|
|
|
| if (panel->expansion_state() != Panel::EXPANDED)
|
| DecrementMinimizedPanels();
|
|
|
| - // Removing an element from the list will invalidate the iterator that refers
|
| - // to it. So we need to check if the dragging panel iterators are affected.
|
| - bool update_original_dragging_iterator_after_erase = false;
|
| - if (dragging_panel_original_iterator_ != panels_.end()) {
|
| - if (dragging_panel_current_iterator_ == iter) {
|
| - // If the dragging panel is being removed, set both dragging iterators to
|
| - // the end of the list.
|
| - dragging_panel_current_iterator_ = dragging_panel_original_iterator_ =
|
| - panels_.end();
|
| - } else if (dragging_panel_original_iterator_ == iter) {
|
| - // If |dragging_panel_original_iterator_| refers to the element being
|
| - // removed, set the flag so that the iterator can be updated to next
|
| - // element.
|
| - update_original_dragging_iterator_after_erase = true;
|
| - }
|
| + if (panel->has_temporary_layout()) {
|
| + panels_in_temporary_layout_.erase(panel);
|
| + return;
|
| }
|
|
|
| - iter = panels_.erase(iter);
|
| -
|
| - if (update_original_dragging_iterator_after_erase)
|
| - dragging_panel_original_iterator_ = iter;
|
| -
|
| - if (!disable_layout_refresh_)
|
| + // Removing an element from the list will invalidate the iterator that refers
|
| + // to it. We need to update the iterator in that case.
|
| + DCHECK(dragging_panel_current_iterator_ == panels_.end() ||
|
| + *dragging_panel_current_iterator_ != panel);
|
| + bool update_iterator_after_erase =
|
| + (dragging_panel_original_iterator_ != panels_.end() &&
|
| + *dragging_panel_original_iterator_ == panel);
|
| +
|
| + // Optimize for the common case of removing the last panel.
|
| + DCHECK(!panels_.empty());
|
| + if (panels_.back() == panel) {
|
| + panels_.pop_back();
|
| + if (update_iterator_after_erase)
|
| + dragging_panel_original_iterator_ = panels_.end();
|
| + // No need to refresh layout as the remaining panels are unaffected.
|
| + // Just check if other panels can now fit in the freed up space.
|
| + panel_manager_->MovePanelsOutOfOverflowIfCanFit();
|
| + } else {
|
| + Panels::iterator iter = find(panels_.begin(), panels_.end(), panel);
|
| + DCHECK(iter != panels_.end());
|
| + iter = panels_.erase(iter);
|
| + if (update_iterator_after_erase)
|
| + dragging_panel_original_iterator_ = iter;
|
| RefreshLayout();
|
| -
|
| - return true;
|
| + }
|
| }
|
|
|
| bool DockedPanelStrip::CanShowPanelAsActive(const Panel* panel) const {
|
| @@ -443,6 +430,10 @@ void DockedPanelStrip::RestorePanel(Panel* panel) {
|
| panel->SetExpansionState(Panel::EXPANDED);
|
| }
|
|
|
| +bool DockedPanelStrip::IsPanelMinimized(const Panel* panel) const {
|
| + return panel->expansion_state() != Panel::EXPANDED;
|
| +}
|
| +
|
| void DockedPanelStrip::IncrementMinimizedPanels() {
|
| minimized_panel_count_++;
|
| if (minimized_panel_count_ == 1)
|
| @@ -679,6 +670,29 @@ void DockedPanelStrip::OnFullScreenModeChanged(bool is_full_screen) {
|
| }
|
| }
|
|
|
| +bool DockedPanelStrip::CanFitPanel(const Panel* panel) const {
|
| + int width = panel->GetRestoredBounds().width();
|
| + return GetRightMostAvailablePosition() - width >= display_area_.x();
|
| +}
|
| +
|
| +int DockedPanelStrip::FitPanelWithWidth(int width) {
|
| + int x = GetRightMostAvailablePosition() - width;
|
| + if (x < display_area_.x()) {
|
| + // Insufficient space for the requested width. Bump panels to overflow.
|
| + Panel* last_panel_to_send_to_overflow;
|
| + for (Panels::reverse_iterator iter = panels_.rbegin();
|
| + iter != panels_.rend(); ++iter) {
|
| + last_panel_to_send_to_overflow = *iter;
|
| + x = last_panel_to_send_to_overflow->GetRestoredBounds().right() - width;
|
| + if (x >= display_area_.x()) {
|
| + panel_manager_->MovePanelsToOverflow(last_panel_to_send_to_overflow);
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + return x;
|
| +}
|
| +
|
| void DockedPanelStrip::RefreshLayout() {
|
| int rightmost_position = StartingRightPosition();
|
|
|
| @@ -705,40 +719,16 @@ void DockedPanelStrip::RefreshLayout() {
|
|
|
| // Add/remove panels from/to overflow. A change in work area or the
|
| // resize/removal of a panel may affect how many panels fit in the strip.
|
| - OverflowPanelStrip* overflow_strip = panel_manager_->overflow_strip();
|
| - if (panel_iter != panels_.end()) {
|
| - // Prevent layout refresh when panel is removed from this strip.
|
| - disable_layout_refresh_ = true;
|
| -
|
| - // Keep track of panels to move to overflow in a separate storage since
|
| - // removing it from the list will invalidate the iterator.
|
| - std::vector<Panel*> panels_to_move_to_overflow;
|
| - for (; panel_iter != panels_.end(); ++panel_iter)
|
| - panels_to_move_to_overflow.push_back(*panel_iter);
|
| -
|
| - // Move panels to overflow in reverse to maintain their order.
|
| - for (std::vector<Panel*>::reverse_iterator iter =
|
| - panels_to_move_to_overflow.rbegin();
|
| - iter != panels_to_move_to_overflow.rend(); ++iter) {
|
| - (*iter)->MoveToStrip(overflow_strip);
|
| - }
|
| -
|
| - disable_layout_refresh_ = false;
|
| - } else {
|
| - // Attempt to add more panels from overflow to the strip.
|
| - Panel* overflow_panel;
|
| - while ((overflow_panel = overflow_strip->first_panel()) &&
|
| - GetRightMostAvailablePosition() >=
|
| - display_area_.x() + overflow_panel->restored_size().width()) {
|
| - overflow_panel->MoveToStrip(this);
|
| - }
|
| - }
|
| + if (panel_iter != panels_.end())
|
| + panel_manager_->MovePanelsToOverflow(*panel_iter);
|
| + else
|
| + panel_manager_->MovePanelsOutOfOverflowIfCanFit();
|
| }
|
|
|
| void DockedPanelStrip::DelayedMovePanelToOverflow(Panel* panel) {
|
| if (panels_in_temporary_layout_.erase(panel)) {
|
| DCHECK(panel->has_temporary_layout());
|
| - panel->MoveToStrip(panel_manager_->overflow_strip());
|
| + panel_manager_->MovePanelToStrip(panel, PanelStrip::IN_OVERFLOW);
|
| }
|
| }
|
|
|
|
|