| Index: chrome/browser/ui/panels/panel_strip.cc
|
| diff --git a/chrome/browser/ui/panels/panel_strip.cc b/chrome/browser/ui/panels/panel_strip.cc
|
| index e62e34bb5383011e9bebd6f733f7be8853f810f3..03289f1c2a6ba81c00d3936ebec19fbe4017e302 100644
|
| --- a/chrome/browser/ui/panels/panel_strip.cc
|
| +++ b/chrome/browser/ui/panels/panel_strip.cc
|
| @@ -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.
|
| 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
|
| // 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.
|
| @@ -53,7 +57,8 @@ PanelStrip::PanelStrip(PanelManager* panel_manager)
|
| dragging_panel_original_x_(0),
|
| delayed_titlebar_action_(NO_ACTION),
|
| remove_delays_for_testing_(false),
|
| - titlebar_action_factory_(this) {
|
| + titlebar_action_factory_(this),
|
| + overflow_action_factory_(this) {
|
| }
|
|
|
| PanelStrip::~PanelStrip() {
|
| @@ -62,12 +67,20 @@ PanelStrip::~PanelStrip() {
|
| DCHECK_EQ(0, minimized_panel_count_);
|
| }
|
|
|
| -void PanelStrip::SetBounds(const gfx::Rect bounds) {
|
| - if (strip_bounds_ == bounds)
|
| +void PanelStrip::SetDisplayArea(const gfx::Rect& new_area) {
|
| + if (display_area_ == new_area)
|
| return;
|
|
|
| - strip_bounds_ = bounds;
|
| - Rearrange(panels_.begin(), StartingRightPosition());
|
| + gfx::Rect old_area = display_area_;
|
| + 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) {
|
| @@ -113,8 +126,21 @@ void PanelStrip::AddNewPanel(Panel* panel) {
|
| panel->set_restored_size(gfx::Size(width, height));
|
|
|
| // Layout the new panel.
|
| - int y = strip_bounds_.bottom() - height;
|
| + int y = display_area_.bottom() - height;
|
| 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));
|
| }
|
|
|
| @@ -122,21 +148,25 @@ void PanelStrip::AddExistingPanel(Panel* panel) {
|
| gfx::Size restored_size = panel->restored_size();
|
| int height = restored_size.height();
|
| int width = restored_size.width();
|
| - int x = GetRightMostAvailablePosition() - width;
|
| - int y = strip_bounds_.bottom() - height;
|
| + int x;
|
| + 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));
|
| }
|
|
|
| int PanelStrip::GetMaxPanelWidth() const {
|
| - return static_cast<int>(strip_bounds_.width() * kPanelMaxWidthFactor);
|
| + return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor);
|
| }
|
|
|
| int PanelStrip::GetMaxPanelHeight() const {
|
| - return strip_bounds_.height();
|
| + return display_area_.height();
|
| }
|
|
|
| int PanelStrip::StartingRightPosition() const {
|
| - return strip_bounds_.right();
|
| + return display_area_.right();
|
| }
|
|
|
| int PanelStrip::GetRightMostAvailablePosition() const {
|
| @@ -155,6 +185,7 @@ bool PanelStrip::Remove(Panel* panel) {
|
| }
|
|
|
| DoRemove(panel);
|
| + Rearrange();
|
| return true;
|
| }
|
|
|
| @@ -162,19 +193,19 @@ void PanelStrip::DelayedRemove() {
|
| for (size_t i = 0; i < panels_pending_to_remove_.size(); ++i)
|
| DoRemove(panels_pending_to_remove_[i]);
|
| 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);
|
| if (iter == panels_.end())
|
| - return;
|
| + return false;
|
|
|
| if (panel->expansion_state() != Panel::EXPANDED)
|
| DecrementMinimizedPanels();
|
|
|
| - gfx::Rect bounds = (*iter)->GetBounds();
|
| - Rearrange(panels_.erase(iter), bounds.right());
|
| - panel_manager_->OnPanelRemoved(panel);
|
| + panels_.erase(iter);
|
| + return true;
|
| }
|
|
|
| void PanelStrip::StartDragging(Panel* panel) {
|
| @@ -351,28 +382,6 @@ void PanelStrip::OnPreferredWindowSizeChanged(
|
| if (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:
|
| // * cannot grow or shrink to go beyond [min_height, max_height]
|
| int new_height = preferred_window_size.height();
|
| @@ -381,19 +390,30 @@ void PanelStrip::OnPreferredWindowSizeChanged(
|
| if (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.
|
| - gfx::Size restored_size = panel->restored_size();
|
| - if (new_height != restored_size.height() &&
|
| + if (new_height != bounds.height() &&
|
| 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);
|
| }
|
|
|
| - gfx::Size new_size = gfx::Size(new_width, new_height);
|
| - if (new_size != restored_size)
|
| - panel->set_restored_size(new_size);
|
| + // Adjust bounds width.
|
| + int delta_x = bounds.width() - new_width;
|
| + if (delta_x != 0) {
|
| + bounds.set_width(new_width);
|
| + bounds.set_x(bounds.x() + delta_x);
|
| + }
|
|
|
| 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 {
|
| @@ -403,7 +423,7 @@ bool PanelStrip::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const {
|
| if (desktop_bar->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM) &&
|
| desktop_bar->GetVisibility(AutoHidingDesktopBar::ALIGN_BOTTOM) ==
|
| AutoHidingDesktopBar::VISIBLE &&
|
| - mouse_y >= strip_bounds_.bottom())
|
| + mouse_y >= display_area_.bottom())
|
| return true;
|
|
|
| for (Panels::const_iterator iter = panels_.begin();
|
| @@ -511,7 +531,7 @@ void PanelStrip::DoBringUpOrDownTitlebars(bool bring_up) {
|
|
|
| int PanelStrip::GetBottomPositionForExpansionState(
|
| 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
|
| // to move the title-only panel above the auto-hiding desktop bar.
|
| AutoHidingDesktopBar* desktop_bar = panel_manager_->auto_hiding_desktop_bar();
|
| @@ -545,11 +565,20 @@ void PanelStrip::OnAutoHidingDesktopBarVisibilityChanged(
|
| delayed_titlebar_action_ = NO_ACTION;
|
| }
|
|
|
| -void PanelStrip::Rearrange(Panels::iterator iter_to_start,
|
| - int rightmost_position) {
|
| - for (Panels::iterator iter = iter_to_start; iter != panels_.end(); ++iter) {
|
| - Panel* panel = *iter;
|
| +void PanelStrip::Rearrange() {
|
| + int rightmost_position = StartingRightPosition();
|
| +
|
| + size_t panel_index = 0;
|
| + for (; panel_index < panels_.size(); ++panel_index) {
|
| + Panel* panel = panels_[panel_index];
|
| 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_y(
|
| GetBottomPositionForExpansionState(panel->expansion_state()) -
|
| @@ -558,6 +587,36 @@ void PanelStrip::Rearrange(Panels::iterator iter_to_start,
|
|
|
| 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() {
|
|
|