Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1508)

Unified Diff: chrome/browser/ui/panels/panel_strip.cc

Issue 8774013: Add panel overflow logic to panel strip. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..b146a682982daf442c9ff59845ba4909de90c4ed 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,21 @@ 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 area) {
+ if (display_area_ == area)
return;
- strip_bounds_ = bounds;
- Rearrange(panels_.begin(), StartingRightPosition());
+ // Check for overflow.
+ if (!panels_.empty() && area.width() < display_area_.width()) {
jianli 2011/12/01 21:36:28 Probably better to set new area 1st so that all la
+ int min_x = display_area_.right() - area.width();
jianli 2011/12/01 21:36:28 display_area_.right() => area.right() It might be
+ while (panels_.back()->GetBounds().x() < min_x) {
+ MovePanelToOverflow(panels_.back(), false);
+ DCHECK(!panels_.empty()); // At least one panel must fit!
jianli 2011/12/01 21:36:28 This might not be always true if the display area
+ }
+ }
+
+ display_area_ = area;
+ Rearrange();
}
void PanelStrip::AddPanel(Panel* panel) {
@@ -113,8 +127,20 @@ 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(),
+ base::Unretained(panel), true), // new panel
jianli 2011/12/01 21:36:28 There could be a case that the new panel is being
jennb 2011/12/01 23:10:17 When the delayed method is called, it checks wheth
+ 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,25 @@ 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);
+
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_PANEL_REMOVED,
+ content::Source<Panel>(panel),
+ content::NotificationService::NoDetails());
+
+ return true;
}
void PanelStrip::StartDragging(Panel* panel) {
@@ -351,28 +388,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 +396,58 @@ 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);
+
+ // Reposition all the panels to the left.
jianli 2011/12/01 21:36:28 I think this logic could be folded into Rearrange
+ 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;
jianli 2011/12/01 21:36:28 extra space after for.
+ --i) {
+ Panel* this_panel = panels_[i];
+ gfx::Rect this_bounds = this_panel->GetBounds();
+ int shifted_x = this_bounds.x() + delta_x;
+ if (delta_x < 0 && shifted_x < display_area_.x()) {
+ MovePanelToOverflow(this_panel, false); // safe to erase from end
+ } else {
+ this_bounds.set_x(shifted_x);
+ this_panel->SetPanelBounds(this_bounds);
+ }
+ }
+
+ // Finally, check if size change caused current panel to overflow.
+ if (bounds.x() < display_area_.x()) {
+ MovePanelToOverflow(panel, false);
+ return;
+ }
+ }
panel->SetPanelBounds(bounds);
+
+ // Try to add more panels to the strip if size decreased.
+ if (delta_x > 0)
+ AddPanelsFromOverflow();
}
bool PanelStrip::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const {
@@ -403,7 +457,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 +565,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,19 +599,42 @@ 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) {
+void PanelStrip::Rearrange() {
+ int rightmost_position = StartingRightPosition();
+ for (Panels::iterator iter = panels_.begin(); iter != panels_.end(); ++iter) {
Panel* panel = *iter;
gfx::Rect new_bounds(panel->GetBounds());
new_bounds.set_x(rightmost_position - new_bounds.width());
new_bounds.set_y(
GetBottomPositionForExpansionState(panel->expansion_state()) -
new_bounds.height());
+ DCHECK(new_bounds.x() >= display_area_.x()); // Should not overflow.
panel->SetPanelBounds(new_bounds);
rightmost_position = new_bounds.x() - kPanelsHorizontalSpacing;
}
+
+ AddPanelsFromOverflow(); // Maybe there's more room now...
+}
+
+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::AddPanelsFromOverflow() {
+ // 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);
+ // AddExistingPanel(candidate);
+ // }
}
void PanelStrip::RemoveAll() {
« chrome/browser/ui/panels/panel_strip.h ('K') | « chrome/browser/ui/panels/panel_strip.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698