Commit a5294d6a authored by jennb@chromium.org's avatar jennb@chromium.org

Add panel overflow logic to panel strip.

* Renamed strip_bounds_ to display_area_ to avoid confusion
thinking it was a flag to remove info.

Overflow not functional until jianli uncomments the overflow
strip code after he implements an overflow strip.

BUG=None
TEST=Disabled PanelBrowserTest.CreatePanelOnOverflow. jianli will fix.

Review URL: http://codereview.chromium.org/8774013

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112572 0039d316-1c4b-4281-b951-d872f2087c98
parent 33047f18
...@@ -533,7 +533,7 @@ IN_PROC_BROWSER_TEST_F(PanelBrowserTest, FindBar) { ...@@ -533,7 +533,7 @@ IN_PROC_BROWSER_TEST_F(PanelBrowserTest, FindBar) {
panel->Close(); panel->Close();
} }
IN_PROC_BROWSER_TEST_F(PanelBrowserTest, CreatePanelOnOverflow) { IN_PROC_BROWSER_TEST_F(PanelBrowserTest, DISABLED_CreatePanelOnOverflow) {
TestCreatePanelOnOverflow(); TestCreatePanelOnOverflow();
} }
......
...@@ -76,7 +76,7 @@ void PanelManager::Layout() { ...@@ -76,7 +76,7 @@ void PanelManager::Layout() {
panel_strip_bounds.set_width(adjusted_work_area_.width() - panel_strip_bounds.set_width(adjusted_work_area_.width() -
kPanelStripLeftMargin - kPanelStripRightMargin); kPanelStripLeftMargin - kPanelStripRightMargin);
panel_strip_bounds.set_height(height); panel_strip_bounds.set_height(height);
panel_strip_->SetBounds(panel_strip_bounds); panel_strip_->SetDisplayArea(panel_strip_bounds);
} }
Panel* PanelManager::CreatePanel(Browser* browser) { Panel* PanelManager::CreatePanel(Browser* browser) {
......
...@@ -27,6 +27,10 @@ const double kPanelDefaultWidthToHeightRatio = 1.62; // golden ratio ...@@ -27,6 +27,10 @@ const double kPanelDefaultWidthToHeightRatio = 1.62; // golden ratio
// Maxmium width of a panel is based on a factor of the entire panel strip. // Maxmium width of a panel is based on a factor of the entire panel strip.
const double kPanelMaxWidthFactor = 0.35; const double kPanelMaxWidthFactor = 0.35;
// New panels that cannot fit in the panel strip are moved to overflow
// after a brief delay.
const int kMoveNewPanelToOverflowDelayMilliseconds = 1500; // arbitrary
// Occasionally some system, like Windows, might not bring up or down the bottom // Occasionally some system, like Windows, might not bring up or down the bottom
// bar when the mouse enters or leaves the bottom screen area. This is the // bar when the mouse enters or leaves the bottom screen area. This is the
// maximum time we will wait for the bottom bar visibility change notification. // maximum time we will wait for the bottom bar visibility change notification.
...@@ -53,7 +57,8 @@ PanelStrip::PanelStrip(PanelManager* panel_manager) ...@@ -53,7 +57,8 @@ PanelStrip::PanelStrip(PanelManager* panel_manager)
dragging_panel_original_x_(0), dragging_panel_original_x_(0),
delayed_titlebar_action_(NO_ACTION), delayed_titlebar_action_(NO_ACTION),
remove_delays_for_testing_(false), remove_delays_for_testing_(false),
titlebar_action_factory_(this) { titlebar_action_factory_(this),
overflow_action_factory_(this) {
} }
PanelStrip::~PanelStrip() { PanelStrip::~PanelStrip() {
...@@ -62,12 +67,20 @@ PanelStrip::~PanelStrip() { ...@@ -62,12 +67,20 @@ PanelStrip::~PanelStrip() {
DCHECK_EQ(0, minimized_panel_count_); DCHECK_EQ(0, minimized_panel_count_);
} }
void PanelStrip::SetBounds(const gfx::Rect bounds) { void PanelStrip::SetDisplayArea(const gfx::Rect& new_area) {
if (strip_bounds_ == bounds) if (display_area_ == new_area)
return; return;
strip_bounds_ = bounds; gfx::Rect old_area = display_area_;
Rearrange(panels_.begin(), StartingRightPosition()); display_area_ = new_area;
if (panels_.empty() || new_area.width() == old_area.width())
return;
if (new_area.width() < old_area.width())
Rearrange();
else
MovePanelsFromOverflowIfNeeded();
} }
void PanelStrip::AddPanel(Panel* panel) { void PanelStrip::AddPanel(Panel* panel) {
...@@ -113,8 +126,21 @@ void PanelStrip::AddNewPanel(Panel* panel) { ...@@ -113,8 +126,21 @@ void PanelStrip::AddNewPanel(Panel* panel) {
panel->set_restored_size(gfx::Size(width, height)); panel->set_restored_size(gfx::Size(width, height));
// Layout the new panel. // Layout the new panel.
int y = strip_bounds_.bottom() - height; int y = display_area_.bottom() - height;
int x = GetRightMostAvailablePosition() - width; int x = GetRightMostAvailablePosition() - width;
// Keep panel visible in the strip even if overlap would occur.
// Panel is moved to overflow from the strip after a delay.
if (x < display_area_.x()) {
x = display_area_.x();
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&PanelStrip::MovePanelToOverflow,
overflow_action_factory_.GetWeakPtr(),
panel,
true), // new panel
kMoveNewPanelToOverflowDelayMilliseconds);
}
panel->Initialize(gfx::Rect(x, y, width, height)); panel->Initialize(gfx::Rect(x, y, width, height));
} }
...@@ -122,21 +148,25 @@ void PanelStrip::AddExistingPanel(Panel* panel) { ...@@ -122,21 +148,25 @@ void PanelStrip::AddExistingPanel(Panel* panel) {
gfx::Size restored_size = panel->restored_size(); gfx::Size restored_size = panel->restored_size();
int height = restored_size.height(); int height = restored_size.height();
int width = restored_size.width(); int width = restored_size.width();
int x = GetRightMostAvailablePosition() - width; int x;
int y = strip_bounds_.bottom() - height; while ((x = GetRightMostAvailablePosition() - width) < display_area_.x()) {
DCHECK(!panels_.empty());
MovePanelToOverflow(panels_.back(), false);
}
int y = display_area_.bottom() - height;
panel->SetPanelBounds(gfx::Rect(x, y, width, height)); panel->SetPanelBounds(gfx::Rect(x, y, width, height));
} }
int PanelStrip::GetMaxPanelWidth() const { int PanelStrip::GetMaxPanelWidth() const {
return static_cast<int>(strip_bounds_.width() * kPanelMaxWidthFactor); return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor);
} }
int PanelStrip::GetMaxPanelHeight() const { int PanelStrip::GetMaxPanelHeight() const {
return strip_bounds_.height(); return display_area_.height();
} }
int PanelStrip::StartingRightPosition() const { int PanelStrip::StartingRightPosition() const {
return strip_bounds_.right(); return display_area_.right();
} }
int PanelStrip::GetRightMostAvailablePosition() const { int PanelStrip::GetRightMostAvailablePosition() const {
...@@ -155,6 +185,7 @@ bool PanelStrip::Remove(Panel* panel) { ...@@ -155,6 +185,7 @@ bool PanelStrip::Remove(Panel* panel) {
} }
DoRemove(panel); DoRemove(panel);
Rearrange();
return true; return true;
} }
...@@ -162,19 +193,19 @@ void PanelStrip::DelayedRemove() { ...@@ -162,19 +193,19 @@ void PanelStrip::DelayedRemove() {
for (size_t i = 0; i < panels_pending_to_remove_.size(); ++i) for (size_t i = 0; i < panels_pending_to_remove_.size(); ++i)
DoRemove(panels_pending_to_remove_[i]); DoRemove(panels_pending_to_remove_[i]);
panels_pending_to_remove_.clear(); panels_pending_to_remove_.clear();
Rearrange();
} }
void PanelStrip::DoRemove(Panel* panel) { bool PanelStrip::DoRemove(Panel* panel) {
Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); Panels::iterator iter = find(panels_.begin(), panels_.end(), panel);
if (iter == panels_.end()) if (iter == panels_.end())
return; return false;
if (panel->expansion_state() != Panel::EXPANDED) if (panel->expansion_state() != Panel::EXPANDED)
DecrementMinimizedPanels(); DecrementMinimizedPanels();
gfx::Rect bounds = (*iter)->GetBounds(); panels_.erase(iter);
Rearrange(panels_.erase(iter), bounds.right()); return true;
panel_manager_->OnPanelRemoved(panel);
} }
void PanelStrip::StartDragging(Panel* panel) { void PanelStrip::StartDragging(Panel* panel) {
...@@ -351,28 +382,6 @@ void PanelStrip::OnPreferredWindowSizeChanged( ...@@ -351,28 +382,6 @@ void PanelStrip::OnPreferredWindowSizeChanged(
if (new_width < panel->min_size().width()) if (new_width < panel->min_size().width())
new_width = panel->min_size().width(); new_width = panel->min_size().width();
if (new_width != bounds.width()) {
int delta = bounds.width() - new_width;
bounds.set_x(bounds.x() + delta);
bounds.set_width(new_width);
// Reposition all the panels on the left.
int panel_index = -1;
for (int i = 0; i < static_cast<int>(panels_.size()); ++i) {
if (panels_[i] == panel) {
panel_index = i;
break;
}
}
DCHECK(panel_index >= 0);
for (int i = static_cast<int>(panels_.size()) -1; i > panel_index;
--i) {
gfx::Rect this_bounds = panels_[i]->GetBounds();
this_bounds.set_x(this_bounds.x() + delta);
panels_[i]->SetPanelBounds(this_bounds);
}
}
// The panel height: // The panel height:
// * cannot grow or shrink to go beyond [min_height, max_height] // * cannot grow or shrink to go beyond [min_height, max_height]
int new_height = preferred_window_size.height(); int new_height = preferred_window_size.height();
...@@ -381,19 +390,30 @@ void PanelStrip::OnPreferredWindowSizeChanged( ...@@ -381,19 +390,30 @@ void PanelStrip::OnPreferredWindowSizeChanged(
if (new_height < panel->min_size().height()) if (new_height < panel->min_size().height())
new_height = panel->min_size().height(); new_height = panel->min_size().height();
// Update restored size.
gfx::Size new_size(new_width, new_height);
if (new_size != panel->restored_size())
panel->set_restored_size(preferred_window_size);
// Only need to adjust bounds height when panel is expanded. // Only need to adjust bounds height when panel is expanded.
gfx::Size restored_size = panel->restored_size(); if (new_height != bounds.height() &&
if (new_height != restored_size.height() &&
panel->expansion_state() == Panel::EXPANDED) { panel->expansion_state() == Panel::EXPANDED) {
bounds.set_y(bounds.y() - new_height + bounds.height()); bounds.set_y(bounds.bottom() - new_height);
bounds.set_height(new_height); bounds.set_height(new_height);
} }
gfx::Size new_size = gfx::Size(new_width, new_height); // Adjust bounds width.
if (new_size != restored_size) int delta_x = bounds.width() - new_width;
panel->set_restored_size(new_size); if (delta_x != 0) {
bounds.set_width(new_width);
bounds.set_x(bounds.x() + delta_x);
}
panel->SetPanelBounds(bounds); panel->SetPanelBounds(bounds);
// Only need to rearrange if panel's width changed.
if (delta_x != 0)
Rearrange();
} }
bool PanelStrip::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { bool PanelStrip::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const {
...@@ -403,7 +423,7 @@ bool PanelStrip::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { ...@@ -403,7 +423,7 @@ bool PanelStrip::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const {
if (desktop_bar->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM) && if (desktop_bar->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM) &&
desktop_bar->GetVisibility(AutoHidingDesktopBar::ALIGN_BOTTOM) == desktop_bar->GetVisibility(AutoHidingDesktopBar::ALIGN_BOTTOM) ==
AutoHidingDesktopBar::VISIBLE && AutoHidingDesktopBar::VISIBLE &&
mouse_y >= strip_bounds_.bottom()) mouse_y >= display_area_.bottom())
return true; return true;
for (Panels::const_iterator iter = panels_.begin(); for (Panels::const_iterator iter = panels_.begin();
...@@ -511,7 +531,7 @@ void PanelStrip::DoBringUpOrDownTitlebars(bool bring_up) { ...@@ -511,7 +531,7 @@ void PanelStrip::DoBringUpOrDownTitlebars(bool bring_up) {
int PanelStrip::GetBottomPositionForExpansionState( int PanelStrip::GetBottomPositionForExpansionState(
Panel::ExpansionState expansion_state) const { Panel::ExpansionState expansion_state) const {
int bottom = strip_bounds_.bottom(); int bottom = display_area_.bottom();
// If there is an auto-hiding desktop bar aligned to the bottom edge, we need // If there is an auto-hiding desktop bar aligned to the bottom edge, we need
// to move the title-only panel above the auto-hiding desktop bar. // to move the title-only panel above the auto-hiding desktop bar.
AutoHidingDesktopBar* desktop_bar = panel_manager_->auto_hiding_desktop_bar(); AutoHidingDesktopBar* desktop_bar = panel_manager_->auto_hiding_desktop_bar();
...@@ -545,11 +565,20 @@ void PanelStrip::OnAutoHidingDesktopBarVisibilityChanged( ...@@ -545,11 +565,20 @@ void PanelStrip::OnAutoHidingDesktopBarVisibilityChanged(
delayed_titlebar_action_ = NO_ACTION; delayed_titlebar_action_ = NO_ACTION;
} }
void PanelStrip::Rearrange(Panels::iterator iter_to_start, void PanelStrip::Rearrange() {
int rightmost_position) { int rightmost_position = StartingRightPosition();
for (Panels::iterator iter = iter_to_start; iter != panels_.end(); ++iter) {
Panel* panel = *iter; size_t panel_index = 0;
for (; panel_index < panels_.size(); ++panel_index) {
Panel* panel = panels_[panel_index];
gfx::Rect new_bounds(panel->GetBounds()); gfx::Rect new_bounds(panel->GetBounds());
int x = rightmost_position - new_bounds.width();
if (x < display_area_.x()) {
MovePanelsToOverflow(panel_index);
break;
}
new_bounds.set_x(rightmost_position - new_bounds.width()); new_bounds.set_x(rightmost_position - new_bounds.width());
new_bounds.set_y( new_bounds.set_y(
GetBottomPositionForExpansionState(panel->expansion_state()) - GetBottomPositionForExpansionState(panel->expansion_state()) -
...@@ -558,6 +587,36 @@ void PanelStrip::Rearrange(Panels::iterator iter_to_start, ...@@ -558,6 +587,36 @@ void PanelStrip::Rearrange(Panels::iterator iter_to_start,
rightmost_position = new_bounds.x() - kPanelsHorizontalSpacing; rightmost_position = new_bounds.x() - kPanelsHorizontalSpacing;
} }
if (panel_index == panels_.size())
MovePanelsFromOverflowIfNeeded();
}
void PanelStrip::MovePanelsToOverflow(size_t overflow_point) {
DCHECK(overflow_point >= 0);
// Move panels in reverse to maintain their order.
for (size_t i = panels_.size() - 1; i >= overflow_point; --i)
MovePanelToOverflow(panels_[i], false);
}
void PanelStrip::MovePanelToOverflow(Panel* panel, bool is_new) {
if (!DoRemove(panel))
return;
// TODO(jianli): Replace with the real code using overflow strip.
// panel_manager_->panel_overflow_strip()->AddPanel(panel, is_new);
}
void PanelStrip::MovePanelsFromOverflowIfNeeded() {
// TODO(jianli): Replace with the real code using overflow strip.
// PanelOverflowStrip* overflow = panel_manager_->panel_overflow_strip();
// Panel* candidate;
// while (candidate = overflow->FirstPanel() &&
// GetRightMostAvailablePosition -
// candidate->GetRestoredSize().width() >= display_area_.x()) {
// overflow->Remove(candidate);
// AddPanel(candidate);
// }
} }
void PanelStrip::RemoveAll() { void PanelStrip::RemoveAll() {
......
...@@ -30,7 +30,7 @@ class PanelStrip : public PanelMouseWatcherObserver { ...@@ -30,7 +30,7 @@ class PanelStrip : public PanelMouseWatcherObserver {
// Sets the bounds of the panel strip. // Sets the bounds of the panel strip.
// |bounds| is in screen coordinates. // |bounds| is in screen coordinates.
void SetBounds(const gfx::Rect bounds); void SetDisplayArea(const gfx::Rect& area);
// Adds a panel to the strip. The panel may be a newly created panel or one // Adds a panel to the strip. The panel may be a newly created panel or one
// that is transitioning from another grouping of panels. // that is transitioning from another grouping of panels.
...@@ -112,13 +112,16 @@ class PanelStrip : public PanelMouseWatcherObserver { ...@@ -112,13 +112,16 @@ class PanelStrip : public PanelMouseWatcherObserver {
// Handles all the panels that're delayed to be removed. // Handles all the panels that're delayed to be removed.
void DelayedRemove(); void DelayedRemove();
// Does the remove. Called from Remove and DelayedRemove. // Does the actual remove. Caller is responsible for rearranging
void DoRemove(Panel* panel); // the panel strip if necessary.
// Returns |false| if panel is not in the strip.
bool DoRemove(Panel* panel);
// Rearranges the positions of the panels starting from the given iterator. // Rearranges the positions of the panels in the strip.
// Handles moving panels to/from overflow area as needed.
// This is called when the display space has been changed, i.e. working // This is called when the display space has been changed, i.e. working
// area being changed or a panel being closed. // area being changed or a panel being closed.
void Rearrange(Panels::iterator iter_to_start, int rightmost_position); void Rearrange();
// Help functions to drag the given panel. // Help functions to drag the given panel.
void DragLeft(); void DragLeft();
...@@ -132,10 +135,24 @@ class PanelStrip : public PanelMouseWatcherObserver { ...@@ -132,10 +135,24 @@ class PanelStrip : public PanelMouseWatcherObserver {
int GetRightMostAvailablePosition() const; int GetRightMostAvailablePosition() const;
// Moves the panel from the panel strip to the overflow area because
// the panel will not fit within the bounds of the panel strip.
// Overflow may occur when new panels are added, the bounds of the strip
// changes, a panel's size grows, a panel is moved from overflow into
// the strip, etc.
void MovePanelToOverflow(Panel* panel, bool is_new);
// Moves panels to the overflow area, starting from the last panel.
// |overflow_point| is the index of the first panel to oveflow.
void MovePanelsToOverflow(size_t overflow_point);
// Adds zero or more panels from overflow as will fit in the panel strip.
void MovePanelsFromOverflowIfNeeded();
PanelManager* panel_manager_; // Weak, owns us. PanelManager* panel_manager_; // Weak, owns us.
// All panels in the panel strip must fit within this area. // All panels in the panel strip must fit within this area.
gfx::Rect strip_bounds_; gfx::Rect display_area_;
Panels panels_; Panels panels_;
...@@ -165,6 +182,9 @@ class PanelStrip : public PanelMouseWatcherObserver { ...@@ -165,6 +182,9 @@ class PanelStrip : public PanelMouseWatcherObserver {
// Owned by MessageLoop after posting. // Owned by MessageLoop after posting.
base::WeakPtrFactory<PanelStrip> titlebar_action_factory_; base::WeakPtrFactory<PanelStrip> titlebar_action_factory_;
// Factory used for moving new panels to overflow after a delay.
base::WeakPtrFactory<PanelStrip> overflow_action_factory_;
static const int kPanelsHorizontalSpacing = 4; static const int kPanelsHorizontalSpacing = 4;
// Absolute minimum width and height for panels, including non-client area. // Absolute minimum width and height for panels, including non-client area.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment