diff options
author | jennb@chromium.org <jennb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-03 01:11:24 +0000 |
---|---|---|
committer | jennb@chromium.org <jennb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-03 01:11:24 +0000 |
commit | 21965e2a68ffb2d4107492e8f739e4391dbe7f38 (patch) | |
tree | 7054c0d00c48b333bae9d5e1ebe8f750b81cf244 /chrome/browser | |
parent | fae1ecd61e45ced03f447a53674e4ba1cd9f77a0 (diff) | |
download | chromium_src-21965e2a68ffb2d4107492e8f739e4391dbe7f38.zip chromium_src-21965e2a68ffb2d4107492e8f739e4391dbe7f38.tar.gz chromium_src-21965e2a68ffb2d4107492e8f739e4391dbe7f38.tar.bz2 |
Cleanup to keep panel from manipulating its panel strip assignment directly.
Only PanelManager adds/removes panels from panel strips.
Only exception is in tests.
BUG=None
TEST=Existing tests.
Review URL: http://codereview.chromium.org/9560002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124806 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/ui/panels/detached_panel_browsertest.cc | 23 | ||||
-rw-r--r-- | chrome/browser/ui/panels/detached_panel_strip.cc | 15 | ||||
-rw-r--r-- | chrome/browser/ui/panels/detached_panel_strip.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/panels/docked_panel_strip.cc | 142 | ||||
-rw-r--r-- | chrome/browser/ui/panels/docked_panel_strip.h | 17 | ||||
-rw-r--r-- | chrome/browser/ui/panels/overflow_panel_strip.cc | 30 | ||||
-rw-r--r-- | chrome/browser/ui/panels/overflow_panel_strip.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel.cc | 41 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel.h | 5 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_manager.cc | 62 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_manager.h | 14 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_overflow_browsertest.cc | 4 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_strip.h | 5 |
13 files changed, 216 insertions, 148 deletions
diff --git a/chrome/browser/ui/panels/detached_panel_browsertest.cc b/chrome/browser/ui/panels/detached_panel_browsertest.cc index b2b5e1b..24e22c1 100644 --- a/chrome/browser/ui/panels/detached_panel_browsertest.cc +++ b/chrome/browser/ui/panels/detached_panel_browsertest.cc @@ -12,8 +12,7 @@ class DetachedPanelBrowserTest : public BasePanelBrowserTest { }; -IN_PROC_BROWSER_TEST_F(DetachedPanelBrowserTest, - DISABLED_CheckDetachedPanelProperties) { +IN_PROC_BROWSER_TEST_F(DetachedPanelBrowserTest, CheckDetachedPanelProperties) { PanelManager* panel_manager = PanelManager::GetInstance(); DetachedPanelStrip* detached_strip = panel_manager->detached_strip(); @@ -27,14 +26,13 @@ IN_PROC_BROWSER_TEST_F(DetachedPanelBrowserTest, // Move panels to detached strip. EXPECT_EQ(2, panel_manager->num_panels()); EXPECT_EQ(0, detached_strip->num_panels()); - panel1->MoveToStrip(detached_strip); - panel2->MoveToStrip(detached_strip); + panel_manager->MovePanelToStrip(panel1, PanelStrip::DETACHED); + panel_manager->MovePanelToStrip(panel2, PanelStrip::DETACHED); EXPECT_EQ(2, panel_manager->num_panels()); EXPECT_EQ(2, detached_strip->num_panels()); - std::vector<Panel*> panels = panel_manager->panels(); - EXPECT_EQ(panel1, panels[0]); - EXPECT_EQ(panel2, panels[1]); + EXPECT_TRUE(detached_strip->HasPanel(panel1)); + EXPECT_TRUE(detached_strip->HasPanel(panel2)); EXPECT_TRUE(panel1->draggable()); EXPECT_TRUE(panel2->draggable()); @@ -44,11 +42,10 @@ IN_PROC_BROWSER_TEST_F(DetachedPanelBrowserTest, IN_PROC_BROWSER_TEST_F(DetachedPanelBrowserTest, DragDetachedPanel) { PanelManager* panel_manager = PanelManager::GetInstance(); - DetachedPanelStrip* detached_strip = panel_manager->detached_strip(); // Create one detached panel. Panel* panel = CreatePanelWithBounds("Panel1", gfx::Rect(0, 0, 250, 200)); - panel->MoveToStrip(detached_strip); + panel_manager->MovePanelToStrip(panel, PanelStrip::DETACHED); // Test that the detached panel can be dragged anywhere. scoped_ptr<NativePanelTesting> panel_testing( @@ -101,10 +98,10 @@ IN_PROC_BROWSER_TEST_F(DetachedPanelBrowserTest, CloseDetachedPanelOnDrag) { Panel* panel2 = CreatePanelWithBounds("Panel2", gfx::Rect(0, 0, 110, 110)); Panel* panel3 = CreatePanelWithBounds("Panel3", gfx::Rect(0, 0, 120, 120)); Panel* panel4 = CreatePanelWithBounds("Panel4", gfx::Rect(0, 0, 130, 130)); - panel1->MoveToStrip(detached_strip); - panel2->MoveToStrip(detached_strip); - panel3->MoveToStrip(detached_strip); - panel4->MoveToStrip(detached_strip); + panel_manager->MovePanelToStrip(panel1, PanelStrip::DETACHED); + panel_manager->MovePanelToStrip(panel2, PanelStrip::DETACHED); + panel_manager->MovePanelToStrip(panel3, PanelStrip::DETACHED); + panel_manager->MovePanelToStrip(panel4, PanelStrip::DETACHED); ASSERT_EQ(4, detached_strip->num_panels()); scoped_ptr<NativePanelTesting> panel1_testing( diff --git a/chrome/browser/ui/panels/detached_panel_strip.cc b/chrome/browser/ui/panels/detached_panel_strip.cc index c1c1a78..acc89a8 100644 --- a/chrome/browser/ui/panels/detached_panel_strip.cc +++ b/chrome/browser/ui/panels/detached_panel_strip.cc @@ -34,12 +34,15 @@ void DetachedPanelStrip::RefreshLayout() { } void DetachedPanelStrip::AddPanel(Panel* panel) { - DCHECK_EQ(this, panel->panel_strip()); + DCHECK_NE(this, panel->panel_strip()); + panel->set_panel_strip(this); panels_.insert(panel); } -bool DetachedPanelStrip::RemovePanel(Panel* panel) { - return panels_.erase(panel) != 0; +void DetachedPanelStrip::RemovePanel(Panel* panel) { + DCHECK_EQ(this, panel->panel_strip()); + panel->set_panel_strip(NULL); + panels_.erase(panel); } void DetachedPanelStrip::CloseAll() { @@ -77,6 +80,12 @@ void DetachedPanelStrip::RestorePanel(Panel* panel) { NOTIMPLEMENTED(); } +bool DetachedPanelStrip::IsPanelMinimized(const Panel* panel) const { + DCHECK_EQ(this, panel->panel_strip()); + NOTIMPLEMENTED(); + return false; +} + bool DetachedPanelStrip::CanShowPanelAsActive(const Panel* panel) const { // All detached panels can be shown as active. return true; diff --git a/chrome/browser/ui/panels/detached_panel_strip.h b/chrome/browser/ui/panels/detached_panel_strip.h index 4ea0c4f..0beedf9 100644 --- a/chrome/browser/ui/panels/detached_panel_strip.h +++ b/chrome/browser/ui/panels/detached_panel_strip.h @@ -28,7 +28,7 @@ class DetachedPanelStrip : public PanelStrip { virtual void SetDisplayArea(const gfx::Rect& display_area) OVERRIDE; virtual void RefreshLayout() OVERRIDE; virtual void AddPanel(Panel* panel) OVERRIDE; - virtual bool RemovePanel(Panel* panel) OVERRIDE; + virtual void RemovePanel(Panel* panel) OVERRIDE; virtual void CloseAll() OVERRIDE; virtual void ResizePanelWindow( Panel* panel, @@ -37,6 +37,7 @@ class DetachedPanelStrip : public PanelStrip { virtual void ActivatePanel(Panel* panel) OVERRIDE; virtual void MinimizePanel(Panel* panel) OVERRIDE; virtual void RestorePanel(Panel* panel) OVERRIDE; + virtual bool IsPanelMinimized(const Panel* panel) const OVERRIDE; virtual bool CanShowPanelAsActive(const Panel* panel) const OVERRIDE; virtual bool CanDragPanel(const Panel* panel) const OVERRIDE; virtual void StartDraggingPanel(Panel* panel) OVERRIDE; diff --git a/chrome/browser/ui/panels/docked_panel_strip.cc b/chrome/browser/ui/panels/docked_panel_strip.cc index 4fa17f3..57a4bee 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) @@ -680,6 +671,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(); @@ -706,40 +720,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); } } diff --git a/chrome/browser/ui/panels/docked_panel_strip.h b/chrome/browser/ui/panels/docked_panel_strip.h index 2fb0029..89cf565 100644 --- a/chrome/browser/ui/panels/docked_panel_strip.h +++ b/chrome/browser/ui/panels/docked_panel_strip.h @@ -43,7 +43,7 @@ class DockedPanelStrip : public PanelStrip, // Adds a panel to the strip. The panel may be a newly created panel or one // that is transitioning from another grouping of panels. virtual void AddPanel(Panel* panel) OVERRIDE; - virtual bool RemovePanel(Panel* panel) OVERRIDE; + virtual void RemovePanel(Panel* panel) OVERRIDE; virtual void CloseAll() OVERRIDE; virtual void ResizePanelWindow( Panel* panel, @@ -52,6 +52,7 @@ class DockedPanelStrip : public PanelStrip, virtual void ActivatePanel(Panel* panel) OVERRIDE; virtual void MinimizePanel(Panel* panel) OVERRIDE; virtual void RestorePanel(Panel* panel) OVERRIDE; + virtual bool IsPanelMinimized(const Panel* panel) const OVERRIDE; virtual bool CanShowPanelAsActive(const Panel* panel) const OVERRIDE; virtual bool CanDragPanel(const Panel* panel) const OVERRIDE; virtual void StartDraggingPanel(Panel* panel) OVERRIDE; @@ -78,6 +79,7 @@ class DockedPanelStrip : public PanelStrip, // do NOT have a temporary layout. int num_panels() const { return panels_.size(); } const Panels& panels() const { return panels_; } + Panel* last_panel() const { return panels_.empty() ? NULL : panels_.back(); } gfx::Rect display_area() const { return display_area_; } @@ -91,6 +93,9 @@ class DockedPanelStrip : public PanelStrip, void OnFullScreenModeChanged(bool is_full_screen); + // Returns |true| if panel can fit in the dock strip. + bool CanFitPanel(const Panel* panel) const; + #ifdef UNIT_TEST int num_temporary_layout_panels() const { return panels_in_temporary_layout_.size(); @@ -123,6 +128,12 @@ class DockedPanelStrip : public PanelStrip, int GetRightMostAvailablePosition() const; + // Determines position in strip where a panel of |width| will fit. + // Other panels in the strip may be moved to overflow to make room. + // Returns x position where a panel of |width| wide can fit. + // |width| is in screen coordinates. + int FitPanelWithWidth(int width); + // Called by AddPanel() after a delay to move a newly created panel from // the panel strip to overflow because the panel could not fit // within the bounds of the panel strip. New panels are first displayed @@ -146,10 +157,6 @@ class DockedPanelStrip : public PanelStrip, int minimized_panel_count_; bool are_titlebars_up_; - // |True| to temporarily prevent refreshing panel layout, e.g. while - // moving panels to overflow area to make room for a panel in this strip. - bool disable_layout_refresh_; - // Referring to current position in |panels_| where the dragging panel // resides. Panels::iterator dragging_panel_current_iterator_; diff --git a/chrome/browser/ui/panels/overflow_panel_strip.cc b/chrome/browser/ui/panels/overflow_panel_strip.cc index 2eeeb90..ce4505b 100644 --- a/chrome/browser/ui/panels/overflow_panel_strip.cc +++ b/chrome/browser/ui/panels/overflow_panel_strip.cc @@ -5,7 +5,6 @@ #include "chrome/browser/ui/panels/overflow_panel_strip.h" #include "base/logging.h" -#include "chrome/browser/ui/panels/docked_panel_strip.h" #include "chrome/browser/ui/panels/panel_manager.h" #include "chrome/browser/ui/panels/panel_mouse_watcher.h" #include "chrome/browser/ui/panels/panel_overflow_indicator.h" @@ -82,7 +81,9 @@ void OverflowPanelStrip::UpdateCurrentWidth() { void OverflowPanelStrip::AddPanel(Panel* panel) { // TODO(jianli): consider using other container to improve the perf for // inserting to the front. http://crbug.com/106222 - DCHECK_EQ(this, panel->panel_strip()); + DCHECK_NE(this, panel->panel_strip()); + panel->set_panel_strip(this); + // Newly created panels that were temporarily in the panel strip // are added to the back of the overflow, whereas panels that are // bumped from the panel strip by other panels go to the front @@ -115,14 +116,16 @@ void OverflowPanelStrip::AddPanel(Panel* panel) { } } -bool OverflowPanelStrip::RemovePanel(Panel* panel) { +void OverflowPanelStrip::RemovePanel(Panel* panel) { + DCHECK_EQ(this, panel->panel_strip()); + panel->set_panel_strip(NULL); + size_t index = 0; Panels::iterator iter = panels_.begin(); for (; iter != panels_.end(); ++iter, ++index) if (*iter == panel) break; - if (iter == panels_.end()) - return false; + DCHECK(iter != panels_.end()); panels_.erase(iter); DoRefresh(index, panels_.size() - 1); @@ -136,8 +139,6 @@ bool OverflowPanelStrip::RemovePanel(Panel* panel) { overflow_indicator_.reset(); else UpdateOverflowIndicatorCount(); - - return true; } void OverflowPanelStrip::CloseAll() { @@ -164,9 +165,8 @@ void OverflowPanelStrip::OnPanelAttentionStateChanged(Panel* panel) { void OverflowPanelStrip::ActivatePanel(Panel* panel) { DCHECK_EQ(this, panel->panel_strip()); // Activating an overflow panel moves it to the docked panel strip. - PanelStrip* docked_strip = panel_manager_->docked_strip(); - panel->MoveToStrip(docked_strip); - docked_strip->ActivatePanel(panel); + panel_manager_->MovePanelToStrip(panel, PanelStrip::DOCKED); + panel->panel_strip()->ActivatePanel(panel); } void OverflowPanelStrip::MinimizePanel(Panel* panel) { @@ -176,9 +176,13 @@ void OverflowPanelStrip::MinimizePanel(Panel* panel) { void OverflowPanelStrip::RestorePanel(Panel* panel) { DCHECK_EQ(this, panel->panel_strip()); - PanelStrip* docked_strip = panel_manager_->docked_strip(); - panel->MoveToStrip(docked_strip); - docked_strip->RestorePanel(panel); + panel_manager_->MovePanelToStrip(panel, PanelStrip::DOCKED); + panel->panel_strip()->RestorePanel(panel); +} + +bool OverflowPanelStrip::IsPanelMinimized(const Panel* panel) const { + // All overflow panels are considered minimized. + return true; } bool OverflowPanelStrip::CanShowPanelAsActive(const Panel* panel) const { diff --git a/chrome/browser/ui/panels/overflow_panel_strip.h b/chrome/browser/ui/panels/overflow_panel_strip.h index 3ffcf5a..511b8c2 100644 --- a/chrome/browser/ui/panels/overflow_panel_strip.h +++ b/chrome/browser/ui/panels/overflow_panel_strip.h @@ -33,7 +33,7 @@ class OverflowPanelStrip : public PanelStrip, virtual void SetDisplayArea(const gfx::Rect& display_area) OVERRIDE; virtual void RefreshLayout() OVERRIDE; virtual void AddPanel(Panel* panel) OVERRIDE; - virtual bool RemovePanel(Panel* panel) OVERRIDE; + virtual void RemovePanel(Panel* panel) OVERRIDE; virtual void CloseAll() OVERRIDE; virtual void ResizePanelWindow( Panel* panel, @@ -42,6 +42,7 @@ class OverflowPanelStrip : public PanelStrip, virtual void ActivatePanel(Panel* panel) OVERRIDE; virtual void MinimizePanel(Panel* panel) OVERRIDE; virtual void RestorePanel(Panel* panel) OVERRIDE; + virtual bool IsPanelMinimized(const Panel* panel) const OVERRIDE; virtual bool CanShowPanelAsActive(const Panel* panel) const OVERRIDE; virtual bool CanDragPanel(const Panel* panel) const OVERRIDE; virtual void StartDraggingPanel(Panel* panel) OVERRIDE; diff --git a/chrome/browser/ui/panels/panel.cc b/chrome/browser/ui/panels/panel.cc index 42917ce..a2e60a3 100644 --- a/chrome/browser/ui/panels/panel.cc +++ b/chrome/browser/ui/panels/panel.cc @@ -68,8 +68,8 @@ void Panel::Initialize(const gfx::Rect& bounds) { void Panel::OnNativePanelClosed() { if (auto_resizable_) native_panel_->GetPanelBrowser()->tabstrip_model()->RemoveObserver(this); - panel_strip_->RemovePanel(this); manager()->OnPanelClosed(this); + DCHECK(!panel_strip_); } PanelManager* Panel::manager() const { @@ -77,7 +77,7 @@ PanelManager* Panel::manager() const { } bool Panel::draggable() const { - return panel_strip()->CanDragPanel(this); + return panel_strip_ && panel_strip_->CanDragPanel(this); } const Extension* Panel::GetExtension() const { @@ -89,7 +89,7 @@ const Extension* Panel::GetExtension() const { // being resized vs a change in current display bounds, e.g. from overflow // size change. Change this when refactoring panel resize logic. void Panel::SetPanelBounds(const gfx::Rect& bounds) { - if (panel_strip_->type() == PanelStrip::DOCKED && + if (panel_strip_ && panel_strip_->type() == PanelStrip::DOCKED && expansion_state_ == Panel::EXPANDED) restored_size_ = bounds.size(); @@ -102,7 +102,7 @@ void Panel::SetPanelBounds(const gfx::Rect& bounds) { } void Panel::SetPanelBoundsInstantly(const gfx::Rect& bounds) { - if (panel_strip_->type() == PanelStrip::DOCKED && + if (panel_strip_ && panel_strip_->type() == PanelStrip::DOCKED && expansion_state_ == Panel::EXPANDED) restored_size_ = bounds.size(); @@ -156,20 +156,6 @@ void Panel::SetAppIconVisibility(bool visible) { native_panel_->SetPanelAppIconVisibility(visible); } -void Panel::MoveToStrip(PanelStrip* new_strip) { - DCHECK_NE(panel_strip_, new_strip); - if (panel_strip_) - panel_strip_->RemovePanel(this); - - panel_strip_ = new_strip; - panel_strip_->AddPanel(this); - - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PANEL_CHANGED_LAYOUT_MODE, - content::Source<Panel>(this), - content::NotificationService::NoDetails()); -} - void Panel::SetExpansionState(ExpansionState new_state) { if (expansion_state_ == new_state) return; @@ -197,7 +183,7 @@ void Panel::FullScreenModeChanged(bool is_full_screen) { } void Panel::Show() { - if (manager()->is_full_screen()) + if (manager()->is_full_screen() || !panel_strip_) return; if (panel_strip_->CanShowPanelAsActive(this)) @@ -207,7 +193,7 @@ void Panel::Show() { } void Panel::ShowInactive() { - if (manager()->is_full_screen()) + if (manager()->is_full_screen() || !panel_strip_) return; native_panel_->ShowPanelInactive(); @@ -225,6 +211,9 @@ void Panel::Close() { } void Panel::Activate() { + if (!panel_strip_) + return; + panel_strip_->ActivatePanel(this); native_panel_->ActivatePanel(); } @@ -238,7 +227,7 @@ bool Panel::IsActive() const { } void Panel::FlashFrame(bool flash) { - if (IsDrawingAttention() == flash) + if (IsDrawingAttention() == flash || !panel_strip_) return; // Don't draw attention for an active panel. @@ -323,9 +312,7 @@ bool Panel::IsMaximized() const { } bool Panel::IsMinimized() const { - PanelStrip::Type strip_type = panel_strip_->type(); - return strip_type == PanelStrip::IN_OVERFLOW || - (strip_type == PanelStrip::DOCKED && expansion_state_ != EXPANDED); + return !panel_strip_ || panel_strip()->IsPanelMinimized(this); } void Panel::Maximize() { @@ -333,11 +320,13 @@ void Panel::Maximize() { } void Panel::Minimize() { - panel_strip_->MinimizePanel(this); + if (panel_strip_) + panel_strip_->MinimizePanel(this); } void Panel::Restore() { - panel_strip_->RestorePanel(this); + if (panel_strip_) + panel_strip_->RestorePanel(this); } void Panel::EnterFullscreen( diff --git a/chrome/browser/ui/panels/panel.h b/chrome/browser/ui/panels/panel.h index 96a5be9..495f05c 100644 --- a/chrome/browser/ui/panels/panel.h +++ b/chrome/browser/ui/panels/panel.h @@ -221,9 +221,8 @@ class Panel : public BrowserWindow, // May be NULL if panel is newly created and has not been positioned yet. PanelStrip* panel_strip() const { return panel_strip_; } - // Moves the panel to the |new_strip|, removing the panel from its - // current strip. - void MoveToStrip(PanelStrip* new_strip); + // Sets the current panel strip that contains this panel. + void set_panel_strip(PanelStrip* new_strip) { panel_strip_ = new_strip; } ExpansionState expansion_state() const { return expansion_state_; } ExpansionState old_expansion_state() const { return old_expansion_state_; } diff --git a/chrome/browser/ui/panels/panel_manager.cc b/chrome/browser/ui/panels/panel_manager.cc index bb8323a..22195b6 100644 --- a/chrome/browser/ui/panels/panel_manager.cc +++ b/chrome/browser/ui/panels/panel_manager.cc @@ -4,6 +4,7 @@ #include "chrome/browser/ui/panels/panel_manager.h" +#include "base/auto_reset.h" #include "base/command_line.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" @@ -64,7 +65,8 @@ bool PanelManager::ShouldUsePanels(const std::string& extension_id) { PanelManager::PanelManager() : panel_mouse_watcher_(PanelMouseWatcher::Create()), auto_sizing_enabled_(true), - is_full_screen_(false) { + is_full_screen_(false), + is_processing_overflow_(false) { detached_strip_.reset(new DetachedPanelStrip(this)); docked_strip_.reset(new DockedPanelStrip(this)); overflow_strip_.reset(new OverflowPanelStrip(this)); @@ -117,7 +119,7 @@ Panel* PanelManager::CreatePanel(Browser* browser) { int width = browser->override_bounds().width(); int height = browser->override_bounds().height(); Panel* panel = new Panel(browser, gfx::Size(width, height)); - panel->MoveToStrip(docked_strip_.get()); + docked_strip_->AddPanel(panel); content::NotificationService::current()->Notify( chrome::NOTIFICATION_PANEL_ADDED, @@ -147,10 +149,11 @@ void PanelManager::CheckFullScreenMode() { } void PanelManager::OnPanelClosed(Panel* panel) { - if (num_panels() == 0) + if (num_panels() == 1) full_screen_mode_timer_.Stop(); drag_controller_->OnPanelClosed(panel); + panel->panel_strip()->RemovePanel(panel); content::NotificationService::current()->Notify( chrome::NOTIFICATION_PANEL_CLOSED, @@ -185,6 +188,59 @@ void PanelManager::ResizePanel(Panel* panel, const gfx::Size& new_size) { panel->SetAutoResizable(false); } +void PanelManager::MovePanelToStrip(Panel* panel, + PanelStrip::Type new_layout) { + DCHECK(panel); + PanelStrip* current_strip = panel->panel_strip(); + DCHECK(current_strip); + DCHECK_NE(current_strip->type(), new_layout); + current_strip->RemovePanel(panel); + + PanelStrip* target_strip = NULL; + switch (new_layout) { + case PanelStrip::DETACHED: + target_strip = detached_strip_.get(); + break; + case PanelStrip::DOCKED: + target_strip = docked_strip_.get(); + break; + case PanelStrip::IN_OVERFLOW: + target_strip = overflow_strip_.get(); + break; + default: + NOTREACHED(); + } + + target_strip->AddPanel(panel); + + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_PANEL_CHANGED_LAYOUT_MODE, + content::Source<Panel>(panel), + content::NotificationService::NoDetails()); +} + +void PanelManager::MovePanelsToOverflow(Panel* last_panel_to_move) { + AutoReset<bool> processing_overflow(&is_processing_overflow_, true); + // Move panels to overflow in reverse to maintain their order. + Panel* bumped_panel; + while ((bumped_panel = docked_strip_->last_panel())) { + MovePanelToStrip(bumped_panel, PanelStrip::IN_OVERFLOW); + if (bumped_panel == last_panel_to_move) + break; + } + DCHECK(!docked_strip_->panels().empty()); +} + +void PanelManager::MovePanelsOutOfOverflowIfCanFit() { + if (is_processing_overflow_) + return; + + Panel* overflow_panel; + while ((overflow_panel = overflow_strip_->first_panel()) && + docked_strip_->CanFitPanel(overflow_panel)) + MovePanelToStrip(overflow_panel, PanelStrip::DOCKED); +} + bool PanelManager::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { return docked_strip_->ShouldBringUpTitlebars(mouse_x, mouse_y); } diff --git a/chrome/browser/ui/panels/panel_manager.h b/chrome/browser/ui/panels/panel_manager.h index 73202a6..3194cf8 100644 --- a/chrome/browser/ui/panels/panel_manager.h +++ b/chrome/browser/ui/panels/panel_manager.h @@ -13,6 +13,7 @@ #include "base/timer.h" #include "chrome/browser/ui/panels/auto_hiding_desktop_bar.h" #include "chrome/browser/ui/panels/panel.h" +#include "chrome/browser/ui/panels/panel_strip.h" #include "ui/gfx/rect.h" class Browser; @@ -61,6 +62,15 @@ class PanelManager : public AutoHidingDesktopBar::Observer { // for panels that are auto-sized. void ResizePanel(Panel* panel, const gfx::Size& new_size); + // Moves the |panel| to a different type of panel strip. + void MovePanelToStrip(Panel* panel, PanelStrip::Type new_layout); + + // Move all panels up to, and including, the |last_panel_to_move| to overflow. + void MovePanelsToOverflow(Panel* last_panel_to_move); + + // Moves as many panels out of overflow as space allows. + void MovePanelsOutOfOverflowIfCanFit(); + // Returns true if we should bring up the titlebars, given the current mouse // point. bool ShouldBringUpTitlebars(int mouse_x, int mouse_y) const; @@ -211,6 +221,10 @@ class PanelManager : public AutoHidingDesktopBar::Observer { // True if current active app is in full screen mode. bool is_full_screen_; + // True only while moving panels to overflow. Used to prevent moving panels + // out of overflow while in the process of moving panels to overflow. + bool is_processing_overflow_; + DISALLOW_COPY_AND_ASSIGN(PanelManager); }; diff --git a/chrome/browser/ui/panels/panel_overflow_browsertest.cc b/chrome/browser/ui/panels/panel_overflow_browsertest.cc index e5b9961..14699bd 100644 --- a/chrome/browser/ui/panels/panel_overflow_browsertest.cc +++ b/chrome/browser/ui/panels/panel_overflow_browsertest.cc @@ -254,9 +254,9 @@ IN_PROC_BROWSER_TEST_F(PanelOverflowBrowserTest, UpdateDraggableStatus) { PanelManager* panel_manager = PanelManager::GetInstance(); Panel* panel = CreatePanel("panel"); EXPECT_TRUE(panel->draggable()); - panel->MoveToStrip(panel_manager->overflow_strip()); + panel_manager->MovePanelToStrip(panel, PanelStrip::IN_OVERFLOW); EXPECT_FALSE(panel->draggable()); - panel->MoveToStrip(panel_manager->docked_strip()); + panel_manager->MovePanelToStrip(panel, PanelStrip::DOCKED); EXPECT_TRUE(panel->draggable()); panel->Close(); } diff --git a/chrome/browser/ui/panels/panel_strip.h b/chrome/browser/ui/panels/panel_strip.h index 7b0bced..c1da8f4 100644 --- a/chrome/browser/ui/panels/panel_strip.h +++ b/chrome/browser/ui/panels/panel_strip.h @@ -36,8 +36,7 @@ class PanelStrip { // Removes |panel| from the collection of panels. Invoked asynchronously // after a panel has been closed. - // Returns |false| if the panel is not in the strip. - virtual bool RemovePanel(Panel* panel) = 0; + virtual void RemovePanel(Panel* panel) = 0; // Closes all panels in the collection. Panels will be removed after closing. virtual void CloseAll() = 0; @@ -62,6 +61,8 @@ class PanelStrip { virtual void MinimizePanel(Panel* panel) = 0; virtual void RestorePanel(Panel* panel) = 0; + virtual bool IsPanelMinimized(const Panel* panel) const = 0; + // Returns true if |panel| can be shown as active. virtual bool CanShowPanelAsActive(const Panel* panel) const = 0; |