| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/panels/panel_manager.h" | 5 #include "chrome/browser/ui/panels/panel_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "chrome/browser/ui/browser.h" | 11 #include "chrome/browser/ui/browser.h" |
| 12 #include "chrome/browser/ui/panels/bottom_bar.h" |
| 12 #include "chrome/browser/ui/window_sizer.h" | 13 #include "chrome/browser/ui/window_sizer.h" |
| 13 | 14 |
| 14 namespace { | 15 namespace { |
| 15 // Invalid panel index. | 16 // Invalid panel index. |
| 16 const size_t kInvalidPanelIndex = static_cast<size_t>(-1); | 17 const size_t kInvalidPanelIndex = static_cast<size_t>(-1); |
| 17 | 18 |
| 18 // Minimum width and height of a panel. | 19 // Minimum width and height of a panel. |
| 19 const int kPanelMinWidthPixels = 64; | 20 const int kPanelMinWidthPixels = 64; |
| 20 const int kPanelMinHeightPixels = 24; | 21 const int kPanelMinHeightPixels = 24; |
| 21 | 22 |
| 22 // Default width and height of a panel. | 23 // Default width and height of a panel. |
| 23 const int kPanelDefaultWidthPixels = 240; | 24 const int kPanelDefaultWidthPixels = 240; |
| 24 const int kPanelDefaultHeightPixels = 290; | 25 const int kPanelDefaultHeightPixels = 290; |
| 25 | 26 |
| 26 // Maxmium width and height of a panel based on the factor of the working | 27 // Maxmium width and height of a panel based on the factor of the working |
| 27 // area. | 28 // area. |
| 28 const double kPanelMaxWidthFactor = 1.0; | 29 const double kPanelMaxWidthFactor = 1.0; |
| 29 const double kPanelMaxHeightFactor = 0.5; | 30 const double kPanelMaxHeightFactor = 0.5; |
| 30 | 31 |
| 31 // Horizontal spacing between two panels. | 32 // Horizontal spacing between two panels. |
| 32 const int kPanelsHorizontalSpacing = 4; | 33 const int kPanelsHorizontalSpacing = 4; |
| 33 | 34 |
| 35 // The polling interval to check if auto-hide bottom bar becomes visible or |
| 36 // hidden so that we can bring up/down panels' titlebar. |
| 37 const int kBottomBarCheckPollingIntervalMs = 50; |
| 38 |
| 34 // Single instance of PanelManager. | 39 // Single instance of PanelManager. |
| 35 scoped_ptr<PanelManager> panel_instance; | 40 scoped_ptr<PanelManager> panel_instance; |
| 36 } // namespace | 41 } // namespace |
| 37 | 42 |
| 38 // static | 43 // static |
| 39 PanelManager* PanelManager::GetInstance() { | 44 PanelManager* PanelManager::GetInstance() { |
| 40 if (!panel_instance.get()) { | 45 if (!panel_instance.get()) { |
| 41 panel_instance.reset(new PanelManager()); | 46 panel_instance.reset(new PanelManager()); |
| 42 } | 47 } |
| 43 return panel_instance.get(); | 48 return panel_instance.get(); |
| 44 } | 49 } |
| 45 | 50 |
| 46 PanelManager::PanelManager() | 51 PanelManager::PanelManager() |
| 47 : max_width_(0), | 52 : auto_hide_bottom_bar_height_(0), |
| 53 max_width_(0), |
| 48 max_height_(0), | 54 max_height_(0), |
| 49 min_x_(0), | |
| 50 current_x_(0), | 55 current_x_(0), |
| 51 bottom_edge_y_(0), | |
| 52 dragging_panel_index_(kInvalidPanelIndex), | 56 dragging_panel_index_(kInvalidPanelIndex), |
| 53 dragging_panel_original_x_(0) { | 57 dragging_panel_original_x_(0), |
| 58 should_check_auto_hide_bottom_bar_on_titlebar_change_(true) { |
| 54 OnDisplayChanged(); | 59 OnDisplayChanged(); |
| 55 } | 60 } |
| 56 | 61 |
| 57 PanelManager::~PanelManager() { | 62 PanelManager::~PanelManager() { |
| 58 DCHECK(panels_.empty()); | 63 DCHECK(panels_.empty()); |
| 59 DCHECK(panels_pending_to_remove_.empty()); | 64 DCHECK(panels_pending_to_remove_.empty()); |
| 60 } | 65 } |
| 61 | 66 |
| 62 void PanelManager::OnDisplayChanged() { | 67 void PanelManager::OnDisplayChanged() { |
| 63 scoped_ptr<WindowSizer::MonitorInfoProvider> info_provider( | 68 scoped_ptr<WindowSizer::MonitorInfoProvider> info_provider( |
| 64 WindowSizer::CreateDefaultMonitorInfoProvider()); | 69 WindowSizer::CreateDefaultMonitorInfoProvider()); |
| 65 SetWorkArea(info_provider->GetPrimaryMonitorWorkArea()); | 70 gfx::Rect work_area = info_provider->GetPrimaryMonitorWorkArea(); |
| 71 |
| 72 int auto_hide_bottom_bar_height = |
| 73 IsBottomBarInAutoHideMode() ? GetBottomBarHeight() : 0; |
| 74 |
| 75 SetWorkArea(work_area, auto_hide_bottom_bar_height); |
| 66 } | 76 } |
| 67 | 77 |
| 68 void PanelManager::SetWorkArea(const gfx::Rect& work_area) { | 78 void PanelManager::SetWorkArea(const gfx::Rect& work_area, |
| 69 if (work_area == work_area_) | 79 int auto_hide_bottom_bar_height) { |
| 80 if (work_area == work_area_ && |
| 81 auto_hide_bottom_bar_height == auto_hide_bottom_bar_height_) |
| 70 return; | 82 return; |
| 71 work_area_ = work_area; | 83 work_area_ = work_area; |
| 84 auto_hide_bottom_bar_height_ = auto_hide_bottom_bar_height; |
| 72 | 85 |
| 73 min_x_ = work_area.x(); | |
| 74 current_x_ = work_area.right(); | 86 current_x_ = work_area.right(); |
| 75 bottom_edge_y_ = work_area.bottom(); | |
| 76 max_width_ = static_cast<int>(work_area.width() * kPanelMaxWidthFactor); | 87 max_width_ = static_cast<int>(work_area.width() * kPanelMaxWidthFactor); |
| 77 max_height_ = static_cast<int>(work_area.height() * kPanelMaxHeightFactor); | 88 max_height_ = static_cast<int>(work_area.height() * kPanelMaxHeightFactor); |
| 78 | 89 |
| 79 Rearrange(panels_.begin()); | 90 Rearrange(panels_.begin()); |
| 80 } | 91 } |
| 81 | 92 |
| 82 void PanelManager::FindAndClosePanelOnOverflow(const Extension* extension) { | 93 void PanelManager::FindAndClosePanelOnOverflow(const Extension* extension) { |
| 83 Panel* panel_to_close = NULL; | 94 Panel* panel_to_close = NULL; |
| 84 | 95 |
| 85 // Try to find the left-most panel invoked from the same extension and close | 96 // Try to find the left-most panel invoked from the same extension and close |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 dragging_panel_bounds_); | 277 dragging_panel_bounds_); |
| 267 } | 278 } |
| 268 | 279 |
| 269 dragging_panel_index_ = kInvalidPanelIndex; | 280 dragging_panel_index_ = kInvalidPanelIndex; |
| 270 | 281 |
| 271 DelayedRemove(); | 282 DelayedRemove(); |
| 272 } | 283 } |
| 273 | 284 |
| 274 bool PanelManager::ShouldBringUpTitleBarForAllMinimizedPanels( | 285 bool PanelManager::ShouldBringUpTitleBarForAllMinimizedPanels( |
| 275 int mouse_x, int mouse_y) const { | 286 int mouse_x, int mouse_y) const { |
| 287 // We should always bring up the title-bar if the mouse is over the auto-hide |
| 288 // task-bar that becomes visible. |
| 289 if (auto_hide_bottom_bar_height_ && |
| 290 mouse_y >= work_area_.bottom() - auto_hide_bottom_bar_height_ && |
| 291 IsBottomBarFullyVisible()) |
| 292 return true; |
| 293 |
| 276 for (Panels::const_iterator iter = panels_.begin(); | 294 for (Panels::const_iterator iter = panels_.begin(); |
| 277 iter != panels_.end(); ++iter) { | 295 iter != panels_.end(); ++iter) { |
| 278 if ((*iter)->ShouldBringUpTitleBar(mouse_x, mouse_y)) | 296 if ((*iter)->ShouldBringUpTitleBar(mouse_x, mouse_y)) |
| 279 return true; | 297 return true; |
| 280 } | 298 } |
| 281 return false; | 299 return false; |
| 282 } | 300 } |
| 283 | 301 |
| 284 void PanelManager::BringUpOrDownTitleBarForAllMinimizedPanels(bool bring_up) { | 302 void PanelManager::BringUpTitleBar() { |
| 303 // If the bottom-bar is in auto-hide mode, delay the bring-up action until |
| 304 // it is fully visible. We do not want both bottom bar and panel titlebar |
| 305 // to pop up at the same time but with different speed. |
| 306 if (!auto_hide_bottom_bar_height_ || |
| 307 !should_check_auto_hide_bottom_bar_on_titlebar_change_ || |
| 308 IsBottomBarFullyVisible()) { |
| 309 bring_up_or_down_titlebar_timer_.Stop(); |
| 310 DoBringUpOrDownTitleBar(true); |
| 311 return; |
| 312 } |
| 313 |
| 314 // Start the timer if not yet. |
| 315 if (!bring_up_or_down_titlebar_timer_.IsRunning()) { |
| 316 bring_up_or_down_titlebar_timer_.Start( |
| 317 base::TimeDelta::FromMilliseconds(kBottomBarCheckPollingIntervalMs), |
| 318 this, |
| 319 &PanelManager::BringUpTitleBar); |
| 320 } |
| 321 } |
| 322 |
| 323 void PanelManager::BringDownTitleBar() { |
| 324 // If the bottom-bar is in auto-hide mode, delay the bring-down action until |
| 325 // it is completely hidden. We do not want both bottom bar and panel titlebar |
| 326 // to pop up at the same time but with different speed. |
| 327 if (!auto_hide_bottom_bar_height_ || |
| 328 !should_check_auto_hide_bottom_bar_on_titlebar_change_ || |
| 329 IsBottomBarHidden()) { |
| 330 bring_up_or_down_titlebar_timer_.Stop(); |
| 331 DoBringUpOrDownTitleBar(false); |
| 332 return; |
| 333 } |
| 334 |
| 335 // Start the timer if not yet. |
| 336 if (!bring_up_or_down_titlebar_timer_.IsRunning()) { |
| 337 bring_up_or_down_titlebar_timer_.Start( |
| 338 base::TimeDelta::FromMilliseconds(kBottomBarCheckPollingIntervalMs), |
| 339 this, |
| 340 &PanelManager::BringDownTitleBar); |
| 341 } |
| 342 } |
| 343 |
| 344 void PanelManager::DoBringUpOrDownTitleBar(bool bring_up) { |
| 285 for (Panels::const_iterator iter = panels_.begin(); | 345 for (Panels::const_iterator iter = panels_.begin(); |
| 286 iter != panels_.end(); ++iter) { | 346 iter != panels_.end(); ++iter) { |
| 287 Panel* panel = *iter; | 347 Panel* panel = *iter; |
| 288 | 348 |
| 289 // Skip any panel that is drawing the attention. | 349 // Skip any panel that is drawing the attention. |
| 290 if (panel->IsDrawingAttention()) | 350 if (panel->IsDrawingAttention()) |
| 291 continue; | 351 continue; |
| 292 | 352 |
| 293 if (bring_up) { | 353 if (bring_up) { |
| 294 if (panel->expansion_state() == Panel::MINIMIZED) | 354 if (panel->expansion_state() == Panel::MINIMIZED) |
| 295 panel->SetExpansionState(Panel::TITLE_ONLY); | 355 panel->SetExpansionState(Panel::TITLE_ONLY); |
| 296 } else { | 356 } else { |
| 297 if (panel->expansion_state() == Panel::TITLE_ONLY) | 357 if (panel->expansion_state() == Panel::TITLE_ONLY) |
| 298 panel->SetExpansionState(Panel::MINIMIZED); | 358 panel->SetExpansionState(Panel::MINIMIZED); |
| 299 } | 359 } |
| 300 } | 360 } |
| 301 } | 361 } |
| 302 | 362 |
| 363 int PanelManager::GetBottomPositionPerExpansionState( |
| 364 Panel::ExpansionState expansion_state) const { |
| 365 int bottom = work_area_.bottom(); |
| 366 if (expansion_state != Panel::MINIMIZED) |
| 367 bottom -= auto_hide_bottom_bar_height_; |
| 368 return bottom; |
| 369 } |
| 370 |
| 303 void PanelManager::Rearrange(Panels::iterator iter_to_start) { | 371 void PanelManager::Rearrange(Panels::iterator iter_to_start) { |
| 304 if (iter_to_start == panels_.end()) | 372 if (iter_to_start == panels_.end()) |
| 305 return; | 373 return; |
| 306 | 374 |
| 307 for (Panels::iterator iter = iter_to_start; iter != panels_.end(); ++iter) { | 375 for (Panels::iterator iter = iter_to_start; iter != panels_.end(); ++iter) { |
| 308 gfx::Rect new_bounds((*iter)->GetBounds()); | 376 gfx::Rect new_bounds((*iter)->GetBounds()); |
| 309 ComputeBoundsForNextPanel(&new_bounds, false); | 377 ComputeBoundsForNextPanel(&new_bounds, false); |
| 310 if (new_bounds != (*iter)->GetBounds()) | 378 if (new_bounds != (*iter)->GetBounds()) |
| 311 (*iter)->SetPanelBounds(new_bounds); | 379 (*iter)->SetPanelBounds(new_bounds); |
| 312 } | 380 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 329 else if (width > max_width_) | 397 else if (width > max_width_) |
| 330 width = max_width_; | 398 width = max_width_; |
| 331 | 399 |
| 332 if (height < kPanelMinHeightPixels) | 400 if (height < kPanelMinHeightPixels) |
| 333 height = kPanelMinHeightPixels; | 401 height = kPanelMinHeightPixels; |
| 334 else if (height > max_height_) | 402 else if (height > max_height_) |
| 335 height = max_height_; | 403 height = max_height_; |
| 336 } | 404 } |
| 337 | 405 |
| 338 int x = current_x_ - width; | 406 int x = current_x_ - width; |
| 339 int y = bottom_edge_y_ - height; | 407 int y = work_area_.bottom() - auto_hide_bottom_bar_height_ - height; |
| 340 | 408 |
| 341 if (x < min_x_) | 409 if (x < work_area_.x()) |
| 342 return false; | 410 return false; |
| 343 | 411 |
| 344 current_x_ -= width + kPanelsHorizontalSpacing; | 412 current_x_ -= width + kPanelsHorizontalSpacing; |
| 345 | 413 |
| 346 bounds->SetRect(x, y, width, height); | 414 bounds->SetRect(x, y, width, height); |
| 347 return true; | 415 return true; |
| 348 } | 416 } |
| 349 | 417 |
| 350 void PanelManager::RemoveAll() { | 418 void PanelManager::RemoveAll() { |
| 351 // This should not be called when we're in the process of dragging. | 419 // This should not be called when we're in the process of dragging. |
| 352 DCHECK(dragging_panel_index_ == kInvalidPanelIndex); | 420 DCHECK(dragging_panel_index_ == kInvalidPanelIndex); |
| 353 | 421 |
| 354 // Start from the bottom to avoid reshuffling. | 422 // Start from the bottom to avoid reshuffling. |
| 355 for (Panels::reverse_iterator iter = panels_.rbegin(); | 423 for (Panels::reverse_iterator iter = panels_.rbegin(); |
| 356 iter != panels_.rend(); ++iter) | 424 iter != panels_.rend(); ++iter) |
| 357 (*iter)->Close(); | 425 (*iter)->Close(); |
| 358 } | 426 } |
| OLD | NEW |