Chromium Code Reviews| Index: chrome/browser/ui/panels/panel_manager.cc |
| =================================================================== |
| --- chrome/browser/ui/panels/panel_manager.cc (revision 97726) |
| +++ chrome/browser/ui/panels/panel_manager.cc (working copy) |
| @@ -8,6 +8,7 @@ |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| +#include "base/message_loop.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/window_sizer.h" |
| @@ -31,27 +32,39 @@ |
| // Horizontal spacing between two panels. |
| const int kPanelsHorizontalSpacing = 4; |
| +// The delayed interval to do the check to ensure we bring up or down titlebars. |
|
Dmitry Titov
2011/08/22 22:35:53
It seems some explanation has to be here. I think
jianli
2011/08/22 23:28:10
The reason for adding this additional logic is tha
|
| +const int kDelayedBringUpOrDownTitlebarsCheckMs = 1000; |
| + |
| // Single instance of PanelManager. |
| -scoped_ptr<PanelManager> panel_instance; |
| +scoped_refptr<PanelManager> panel_instance; |
| } // namespace |
| // static |
| PanelManager* PanelManager::GetInstance() { |
| if (!panel_instance.get()) { |
| - panel_instance.reset(new PanelManager()); |
| + panel_instance = new PanelManager(); |
| + panel_instance->Init(); |
| } |
| return panel_instance.get(); |
| } |
| +// static |
| +void PanelManager::CreateForTesting(const gfx::Rect& work_area, |
| + AutoHideBottomBar* auto_hide_bottom_bar) { |
| + DCHECK(!panel_instance.get()); |
| + panel_instance = new PanelManager(); |
| + panel_instance->auto_hide_bottom_bar_ = auto_hide_bottom_bar; |
| + panel_instance->SetWorkArea(work_area); |
| +} |
| + |
| PanelManager::PanelManager() |
| : max_width_(0), |
| max_height_(0), |
| - min_x_(0), |
| current_x_(0), |
| - bottom_edge_y_(0), |
| dragging_panel_index_(kInvalidPanelIndex), |
| - dragging_panel_original_x_(0) { |
| - OnDisplayChanged(); |
| + dragging_panel_original_x_(0), |
| + delayed_titlebar_action_(NO_ACTION), |
| + ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
| } |
| PanelManager::~PanelManager() { |
| @@ -59,6 +72,11 @@ |
| DCHECK(panels_pending_to_remove_.empty()); |
| } |
| +void PanelManager::Init() { |
| + auto_hide_bottom_bar_ = AutoHideBottomBar::Create(this); |
| + OnDisplayChanged(); |
| +} |
| + |
| void PanelManager::OnDisplayChanged() { |
| scoped_ptr<WindowSizer::MonitorInfoProvider> info_provider( |
| WindowSizer::CreateDefaultMonitorInfoProvider()); |
| @@ -70,9 +88,9 @@ |
| return; |
| work_area_ = work_area; |
| - min_x_ = work_area.x(); |
| + auto_hide_bottom_bar_->UpdateWorkArea(work_area); |
| + |
| current_x_ = work_area.right(); |
| - bottom_edge_y_ = work_area.bottom(); |
| max_width_ = static_cast<int>(work_area.width() * kPanelMaxWidthFactor); |
| max_height_ = static_cast<int>(work_area.height() * kPanelMaxHeightFactor); |
| @@ -271,8 +289,14 @@ |
| DelayedRemove(); |
| } |
| -bool PanelManager::ShouldBringUpTitlebarForAllMinimizedPanels( |
| - int mouse_x, int mouse_y) const { |
| +bool PanelManager::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { |
| + // We should always bring up the title-bar if the mouse is over the auto-hide |
| + // task-bar that becomes visible. |
| + if (auto_hide_bottom_bar_->Exists() && |
| + auto_hide_bottom_bar_->GetVisibility() == AutoHideBottomBar::VISIBLE && |
| + mouse_y >= work_area_.bottom() - auto_hide_bottom_bar_->GetHeight()) |
| + return true; |
| + |
| for (Panels::const_iterator iter = panels_.begin(); |
| iter != panels_.end(); ++iter) { |
| if ((*iter)->ShouldBringUpTitlebar(mouse_x, mouse_y)) |
| @@ -281,7 +305,52 @@ |
| return false; |
| } |
| -void PanelManager::BringUpOrDownTitlebarForAllMinimizedPanels(bool bring_up) { |
| +void PanelManager::BringUpOrDownTitlebars(bool bring_up) { |
| + // If the auto-hide bottom bar exists, delay the action until the bottom |
| + // bar is fully visible or hidden. We do not want both bottom bar and panel |
| + // titlebar to move at the same time but with different speeds. |
| + if (auto_hide_bottom_bar_->Exists()) { |
| + AutoHideBottomBar::Visibility visibility = |
| + auto_hide_bottom_bar_->GetVisibility(); |
| + if (visibility != (bring_up ? AutoHideBottomBar::VISIBLE |
| + : AutoHideBottomBar::HIDDEN)) { |
| + // OnAutoHideBottomBarVisibilityChanged will handle this. |
| + delayed_titlebar_action_ = bring_up ? BRING_UP : BRING_DOWN; |
| + |
| + // Sometimes, the bottom bar does not appear or hide promptly. Schedule |
| + // a delayed task to make sure our delayed action is performed. |
| + MessageLoop::current()->PostDelayedTask( |
| + FROM_HERE, |
| + method_factory_.NewRunnableMethod( |
| + &PanelManager::DelayedBringUpOrDownTitlebarsCheck), |
| + kDelayedBringUpOrDownTitlebarsCheckMs); |
| + |
| + return; |
| + } |
| + } |
| + |
| + DoBringUpOrDownTitlebars(bring_up); |
| +} |
| + |
| +void PanelManager::DelayedBringUpOrDownTitlebarsCheck() { |
| + switch (delayed_titlebar_action_) { |
| + case NO_ACTION: |
| + break; |
| + case BRING_UP: |
| + delayed_titlebar_action_ = NO_ACTION; |
| + DoBringUpOrDownTitlebars(true); |
| + break; |
| + case BRING_DOWN: |
| + delayed_titlebar_action_ = NO_ACTION; |
| + DoBringUpOrDownTitlebars(false); |
| + break; |
| + default: |
| + NOTREACHED(); |
| + break; |
| + } |
| +} |
| + |
| +void PanelManager::DoBringUpOrDownTitlebars(bool bring_up) { |
| for (Panels::const_iterator iter = panels_.begin(); |
| iter != panels_.end(); ++iter) { |
| Panel* panel = *iter; |
| @@ -300,6 +369,42 @@ |
| } |
| } |
| +int PanelManager::GetBottomPositionForExpansionState( |
| + Panel::ExpansionState expansion_state) const { |
| + int bottom = work_area_.bottom(); |
| + if (expansion_state != Panel::MINIMIZED) |
| + bottom -= auto_hide_bottom_bar_->GetHeight(); |
| + return bottom; |
| +} |
| + |
| +void PanelManager::OnAutoHideBottomBarVisibilityChanged( |
| + AutoHideBottomBar::Visibility visibility) { |
| + switch (delayed_titlebar_action_) { |
| + case NO_ACTION: |
| + break; |
| + case BRING_UP: |
| + if (visibility == AutoHideBottomBar::VISIBLE) { |
| + delayed_titlebar_action_ = NO_ACTION; |
| + DoBringUpOrDownTitlebars(true); |
| + } |
| + break; |
| + case BRING_DOWN: |
| + if (visibility == AutoHideBottomBar::HIDDEN) { |
| + delayed_titlebar_action_ = NO_ACTION; |
| + DoBringUpOrDownTitlebars(false); |
| + } |
| + break; |
| + default: |
| + NOTREACHED(); |
| + break; |
| + } |
| +} |
| + |
| +void PanelManager::OnAutoHideBottomBarHeightChanged(int height) { |
| + current_x_ = work_area_.right(); |
| + Rearrange(panels_.begin()); |
| +} |
| + |
| void PanelManager::Rearrange(Panels::iterator iter_to_start) { |
| if (iter_to_start == panels_.end()) |
| return; |
| @@ -336,9 +441,9 @@ |
| } |
| int x = current_x_ - width; |
| - int y = bottom_edge_y_ - height; |
| + int y = work_area_.bottom() - auto_hide_bottom_bar_->GetHeight() - height; |
| - if (x < min_x_) |
| + if (x < work_area_.x()) |
| return false; |
| current_x_ -= width + kPanelsHorizontalSpacing; |