| 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 "base/message_loop.h" |
| 11 #include "chrome/browser/ui/browser.h" | 12 #include "chrome/browser/ui/browser.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 |
| 32 // Occasionally some system, like Windows, might not bring up or down the bottom |
| 33 // bar when the mouse enters or leaves the bottom screen area. This is the |
| 34 // maximum time we will wait for the bottom bar visibility change notification. |
| 35 // After the time expires, we bring up/down the titlebars as planned. |
| 36 const int kMaxMillisecondsWaitForBottomBarVisibilityChange = 1000; |
| 37 |
| 31 // Single instance of PanelManager. | 38 // Single instance of PanelManager. |
| 32 scoped_ptr<PanelManager> panel_instance; | 39 scoped_refptr<PanelManager> panel_instance; |
| 33 } // namespace | 40 } // namespace |
| 34 | 41 |
| 35 // static | 42 // static |
| 36 PanelManager* PanelManager::GetInstance() { | 43 PanelManager* PanelManager::GetInstance() { |
| 37 if (!panel_instance.get()) { | 44 if (!panel_instance.get()) |
| 38 panel_instance.reset(new PanelManager()); | 45 panel_instance = new PanelManager(); |
| 39 } | |
| 40 return panel_instance.get(); | 46 return panel_instance.get(); |
| 41 } | 47 } |
| 42 | 48 |
| 43 PanelManager::PanelManager() | 49 PanelManager::PanelManager() |
| 44 : max_width_(0), | 50 : dragging_panel_index_(kInvalidPanelIndex), |
| 45 max_height_(0), | 51 dragging_panel_original_x_(0), |
| 46 min_x_(0), | 52 delayed_titlebar_action_(NO_ACTION), |
| 47 current_x_(0), | 53 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
| 48 bottom_edge_y_(0), | 54 auto_hiding_desktop_bar_ = AutoHidingDesktopBar::Create(this); |
| 49 dragging_panel_index_(kInvalidPanelIndex), | |
| 50 dragging_panel_original_x_(0) { | |
| 51 OnDisplayChanged(); | 55 OnDisplayChanged(); |
| 52 } | 56 } |
| 53 | 57 |
| 54 PanelManager::~PanelManager() { | 58 PanelManager::~PanelManager() { |
| 55 DCHECK(panels_.empty()); | 59 DCHECK(panels_.empty()); |
| 56 DCHECK(panels_pending_to_remove_.empty()); | 60 DCHECK(panels_pending_to_remove_.empty()); |
| 57 } | 61 } |
| 58 | 62 |
| 59 void PanelManager::OnDisplayChanged() { | 63 void PanelManager::OnDisplayChanged() { |
| 60 scoped_ptr<WindowSizer::MonitorInfoProvider> info_provider( | 64 scoped_ptr<WindowSizer::MonitorInfoProvider> info_provider( |
| 61 WindowSizer::CreateDefaultMonitorInfoProvider()); | 65 WindowSizer::CreateDefaultMonitorInfoProvider()); |
| 62 SetWorkArea(info_provider->GetPrimaryMonitorWorkArea()); | 66 SetWorkArea(info_provider->GetPrimaryMonitorWorkArea()); |
| 63 } | 67 } |
| 64 | 68 |
| 65 void PanelManager::SetWorkArea(const gfx::Rect& work_area) { | 69 void PanelManager::SetWorkArea(const gfx::Rect& work_area) { |
| 66 if (work_area == work_area_) | 70 if (work_area == work_area_) |
| 67 return; | 71 return; |
| 68 work_area_ = work_area; | 72 work_area_ = work_area; |
| 69 | 73 |
| 70 min_x_ = work_area.x(); | 74 auto_hiding_desktop_bar_->UpdateWorkArea(work_area_); |
| 71 current_x_ = work_area.right(); | 75 AdjustWorkAreaForAutoHidingDesktopBars(); |
| 72 bottom_edge_y_ = work_area.bottom(); | |
| 73 max_width_ = static_cast<int>(work_area.width() * kPanelMaxWidthFactor); | |
| 74 max_height_ = static_cast<int>(work_area.height() * kPanelMaxHeightFactor); | |
| 75 | 76 |
| 76 Rearrange(panels_.begin()); | 77 Rearrange(panels_.begin(), adjusted_work_area_.right()); |
| 77 } | 78 } |
| 78 | 79 |
| 79 void PanelManager::FindAndClosePanelOnOverflow(const Extension* extension) { | 80 void PanelManager::FindAndClosePanelOnOverflow(const Extension* extension) { |
| 80 Panel* panel_to_close = NULL; | 81 Panel* panel_to_close = NULL; |
| 81 | 82 |
| 82 // Try to find the left-most panel invoked from the same extension and close | 83 // Try to find the left-most panel invoked from the same extension and close |
| 83 // it. | 84 // it. |
| 84 for (Panels::reverse_iterator iter = panels_.rbegin(); | 85 for (Panels::reverse_iterator iter = panels_.rbegin(); |
| 85 iter != panels_.rend(); ++iter) { | 86 iter != panels_.rend(); ++iter) { |
| 86 if (extension == Panel::GetExtension((*iter)->browser())) { | 87 if (extension == Panel::GetExtension((*iter)->browser())) { |
| 87 panel_to_close = *iter; | 88 panel_to_close = *iter; |
| 88 break; | 89 break; |
| 89 } | 90 } |
| 90 } | 91 } |
| 91 | 92 |
| 92 // If none is found, just pick the left-most panel. | 93 // If none is found, just pick the left-most panel. |
| 93 if (!panel_to_close) | 94 if (!panel_to_close) |
| 94 panel_to_close = panels_.back(); | 95 panel_to_close = panels_.back(); |
| 95 | 96 |
| 96 panel_to_close->Close(); | 97 panel_to_close->Close(); |
| 97 } | 98 } |
| 98 | 99 |
| 99 Panel* PanelManager::CreatePanel(Browser* browser) { | 100 Panel* PanelManager::CreatePanel(Browser* browser) { |
| 101 // Adjust the width and height to fit into our constraint. |
| 102 int width = browser->override_bounds().width(); |
| 103 int height = browser->override_bounds().height(); |
| 104 |
| 105 if (width == 0 && height == 0) { |
| 106 width = kPanelDefaultWidthPixels; |
| 107 height = kPanelDefaultHeightPixels; |
| 108 } |
| 109 |
| 110 int max_panel_width = |
| 111 static_cast<int>(adjusted_work_area_.width() * kPanelMaxWidthFactor); |
| 112 int max_panel_height = |
| 113 static_cast<int>(adjusted_work_area_.height() * kPanelMaxHeightFactor); |
| 114 |
| 115 if (width < kPanelMinWidthPixels) |
| 116 width = kPanelMinWidthPixels; |
| 117 else if (width > max_panel_width) |
| 118 width = max_panel_width; |
| 119 |
| 120 if (height < kPanelMinHeightPixels) |
| 121 height = kPanelMinHeightPixels; |
| 122 else if (height > max_panel_height) |
| 123 height = max_panel_height; |
| 124 |
| 125 // Compute the origin. Ensure that it falls within the adjusted work area by |
| 126 // closing other panels if needed. |
| 127 int y = adjusted_work_area_.bottom() - height; |
| 128 |
| 100 const Extension* extension = NULL; | 129 const Extension* extension = NULL; |
| 101 gfx::Rect bounds = browser->override_bounds(); | 130 int x; |
| 102 while (!ComputeBoundsForNextPanel(&bounds, true)) { | 131 while ((x = GetRightMostAvaialblePosition() - width) < |
| 132 adjusted_work_area_.x() ) { |
| 103 if (!extension) | 133 if (!extension) |
| 104 extension = Panel::GetExtension(browser); | 134 extension = Panel::GetExtension(browser); |
| 105 FindAndClosePanelOnOverflow(extension); | 135 FindAndClosePanelOnOverflow(extension); |
| 106 } | 136 } |
| 107 | 137 |
| 108 Panel* panel = new Panel(browser, bounds); | 138 // Now create the panel with the computed bounds. |
| 139 Panel* panel = new Panel(browser, gfx::Rect(x, y, width, height)); |
| 109 panels_.push_back(panel); | 140 panels_.push_back(panel); |
| 110 | 141 |
| 111 return panel; | 142 return panel; |
| 112 } | 143 } |
| 113 | 144 |
| 145 int PanelManager::GetRightMostAvaialblePosition() const { |
| 146 return panels_.empty() ? adjusted_work_area_.right() : |
| 147 (panels_.back()->GetBounds().x() - kPanelsHorizontalSpacing); |
| 148 } |
| 149 |
| 114 void PanelManager::Remove(Panel* panel) { | 150 void PanelManager::Remove(Panel* panel) { |
| 115 // If we're in the process of dragging, delay the removal. | 151 // If we're in the process of dragging, delay the removal. |
| 116 if (dragging_panel_index_ != kInvalidPanelIndex) { | 152 if (dragging_panel_index_ != kInvalidPanelIndex) { |
| 117 panels_pending_to_remove_.push_back(panel); | 153 panels_pending_to_remove_.push_back(panel); |
| 118 return; | 154 return; |
| 119 } | 155 } |
| 120 | 156 |
| 121 DoRemove(panel); | 157 DoRemove(panel); |
| 122 } | 158 } |
| 123 | 159 |
| 124 void PanelManager::DelayedRemove() { | 160 void PanelManager::DelayedRemove() { |
| 125 for (size_t i = 0; i < panels_pending_to_remove_.size(); ++i) | 161 for (size_t i = 0; i < panels_pending_to_remove_.size(); ++i) |
| 126 DoRemove(panels_pending_to_remove_[i]); | 162 DoRemove(panels_pending_to_remove_[i]); |
| 127 panels_pending_to_remove_.clear(); | 163 panels_pending_to_remove_.clear(); |
| 128 } | 164 } |
| 129 | 165 |
| 130 void PanelManager::DoRemove(Panel* panel) { | 166 void PanelManager::DoRemove(Panel* panel) { |
| 131 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); | 167 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); |
| 132 if (iter == panels_.end()) | 168 if (iter == panels_.end()) |
| 133 return; | 169 return; |
| 134 | 170 |
| 135 gfx::Rect bounds = (*iter)->GetBounds(); | 171 gfx::Rect bounds = (*iter)->GetBounds(); |
| 136 current_x_ = bounds.x() + bounds.width(); | 172 Rearrange(panels_.erase(iter), bounds.right()); |
| 137 Rearrange(panels_.erase(iter)); | |
| 138 } | 173 } |
| 139 | 174 |
| 140 void PanelManager::StartDragging(Panel* panel) { | 175 void PanelManager::StartDragging(Panel* panel) { |
| 141 for (size_t i = 0; i < panels_.size(); ++i) { | 176 for (size_t i = 0; i < panels_.size(); ++i) { |
| 142 if (panels_[i] == panel) { | 177 if (panels_[i] == panel) { |
| 143 dragging_panel_index_ = i; | 178 dragging_panel_index_ = i; |
| 144 dragging_panel_bounds_ = panel->GetBounds(); | 179 dragging_panel_bounds_ = panel->GetBounds(); |
| 145 dragging_panel_original_x_ = dragging_panel_bounds_.x(); | 180 dragging_panel_original_x_ = dragging_panel_bounds_.x(); |
| 146 break; | 181 break; |
| 147 } | 182 } |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 } else { | 296 } else { |
| 262 panels_[dragging_panel_index_]->SetPanelBounds( | 297 panels_[dragging_panel_index_]->SetPanelBounds( |
| 263 dragging_panel_bounds_); | 298 dragging_panel_bounds_); |
| 264 } | 299 } |
| 265 | 300 |
| 266 dragging_panel_index_ = kInvalidPanelIndex; | 301 dragging_panel_index_ = kInvalidPanelIndex; |
| 267 | 302 |
| 268 DelayedRemove(); | 303 DelayedRemove(); |
| 269 } | 304 } |
| 270 | 305 |
| 271 bool PanelManager::ShouldBringUpTitlebarForAllMinimizedPanels( | 306 bool PanelManager::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { |
| 272 int mouse_x, int mouse_y) const { | 307 // We should always bring up the titlebar if the mouse is over the |
| 308 // visible auto-hiding bottom bar. |
| 309 if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM) && |
| 310 auto_hiding_desktop_bar_->GetVisibility( |
| 311 AutoHidingDesktopBar::ALIGN_BOTTOM) == |
| 312 AutoHidingDesktopBar::VISIBLE && |
| 313 mouse_y >= adjusted_work_area_.bottom()) |
| 314 return true; |
| 315 |
| 273 for (Panels::const_iterator iter = panels_.begin(); | 316 for (Panels::const_iterator iter = panels_.begin(); |
| 274 iter != panels_.end(); ++iter) { | 317 iter != panels_.end(); ++iter) { |
| 275 if ((*iter)->ShouldBringUpTitlebar(mouse_x, mouse_y)) | 318 if ((*iter)->ShouldBringUpTitlebar(mouse_x, mouse_y)) |
| 276 return true; | 319 return true; |
| 277 } | 320 } |
| 278 return false; | 321 return false; |
| 279 } | 322 } |
| 280 | 323 |
| 281 void PanelManager::BringUpOrDownTitlebarForAllMinimizedPanels(bool bring_up) { | 324 void PanelManager::BringUpOrDownTitlebars(bool bring_up) { |
| 325 // If the auto-hiding bottom bar exists, delay the action until the bottom |
| 326 // bar is fully visible or hidden. We do not want both bottom bar and panel |
| 327 // titlebar to move at the same time but with different speeds. |
| 328 if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM)) { |
| 329 AutoHidingDesktopBar::Visibility visibility = auto_hiding_desktop_bar_-> |
| 330 GetVisibility(AutoHidingDesktopBar::ALIGN_BOTTOM); |
| 331 if (visibility != (bring_up ? AutoHidingDesktopBar::VISIBLE |
| 332 : AutoHidingDesktopBar::HIDDEN)) { |
| 333 // OnAutoHidingDesktopBarVisibilityChanged will handle this. |
| 334 delayed_titlebar_action_ = bring_up ? BRING_UP : BRING_DOWN; |
| 335 |
| 336 // Occasionally some system, like Windows, might not bring up or down the |
| 337 // bottom bar when the mouse enters or leaves the bottom screen area. |
| 338 // Thus, we schedule a delayed task to do the work if we do not receive |
| 339 // the bottom bar visibility change notification within a certain period |
| 340 // of time. |
| 341 MessageLoop::current()->PostDelayedTask( |
| 342 FROM_HERE, |
| 343 method_factory_.NewRunnableMethod( |
| 344 &PanelManager::DelayedBringUpOrDownTitlebarsCheck), |
| 345 kMaxMillisecondsWaitForBottomBarVisibilityChange); |
| 346 |
| 347 return; |
| 348 } |
| 349 } |
| 350 |
| 351 DoBringUpOrDownTitlebars(bring_up); |
| 352 } |
| 353 |
| 354 void PanelManager::DelayedBringUpOrDownTitlebarsCheck() { |
| 355 if (delayed_titlebar_action_ == NO_ACTION) |
| 356 return; |
| 357 |
| 358 DoBringUpOrDownTitlebars(delayed_titlebar_action_ == BRING_UP); |
| 359 delayed_titlebar_action_ = NO_ACTION; |
| 360 } |
| 361 |
| 362 void PanelManager::DoBringUpOrDownTitlebars(bool bring_up) { |
| 282 for (Panels::const_iterator iter = panels_.begin(); | 363 for (Panels::const_iterator iter = panels_.begin(); |
| 283 iter != panels_.end(); ++iter) { | 364 iter != panels_.end(); ++iter) { |
| 284 Panel* panel = *iter; | 365 Panel* panel = *iter; |
| 285 | 366 |
| 286 // Skip any panel that is drawing the attention. | 367 // Skip any panel that is drawing the attention. |
| 287 if (panel->IsDrawingAttention()) | 368 if (panel->IsDrawingAttention()) |
| 288 continue; | 369 continue; |
| 289 | 370 |
| 290 if (bring_up) { | 371 if (bring_up) { |
| 291 if (panel->expansion_state() == Panel::MINIMIZED) | 372 if (panel->expansion_state() == Panel::MINIMIZED) |
| 292 panel->SetExpansionState(Panel::TITLE_ONLY); | 373 panel->SetExpansionState(Panel::TITLE_ONLY); |
| 293 } else { | 374 } else { |
| 294 if (panel->expansion_state() == Panel::TITLE_ONLY) | 375 if (panel->expansion_state() == Panel::TITLE_ONLY) |
| 295 panel->SetExpansionState(Panel::MINIMIZED); | 376 panel->SetExpansionState(Panel::MINIMIZED); |
| 296 } | 377 } |
| 297 } | 378 } |
| 298 } | 379 } |
| 299 | 380 |
| 300 void PanelManager::Rearrange(Panels::iterator iter_to_start) { | 381 void PanelManager::AdjustWorkAreaForAutoHidingDesktopBars() { |
| 382 // Note that we do not care about the desktop bar aligned to the top edge |
| 383 // since panels could not reach so high due to size constraint. |
| 384 adjusted_work_area_ = work_area_; |
| 385 if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM)) { |
| 386 int space = auto_hiding_desktop_bar_->GetThickness( |
| 387 AutoHidingDesktopBar::ALIGN_BOTTOM); |
| 388 adjusted_work_area_.set_height(adjusted_work_area_.height() - space); |
| 389 } |
| 390 if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_LEFT)) { |
| 391 int space = auto_hiding_desktop_bar_->GetThickness( |
| 392 AutoHidingDesktopBar::ALIGN_LEFT); |
| 393 adjusted_work_area_.set_x(adjusted_work_area_.x() + space); |
| 394 adjusted_work_area_.set_width(adjusted_work_area_.width() - space); |
| 395 } |
| 396 if (auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_RIGHT)) { |
| 397 int space = auto_hiding_desktop_bar_->GetThickness( |
| 398 AutoHidingDesktopBar::ALIGN_RIGHT); |
| 399 adjusted_work_area_.set_width(adjusted_work_area_.width() - space); |
| 400 } |
| 401 } |
| 402 |
| 403 int PanelManager::GetBottomPositionForExpansionState( |
| 404 Panel::ExpansionState expansion_state) const { |
| 405 // If there is an auto-hiding desktop bar aligned to the bottom edge, we need |
| 406 // to move the minimize panel down to the bottom edge. |
| 407 int bottom = adjusted_work_area_.bottom(); |
| 408 if (expansion_state == Panel::MINIMIZED && |
| 409 auto_hiding_desktop_bar_->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM)) { |
| 410 bottom += auto_hiding_desktop_bar_->GetThickness( |
| 411 AutoHidingDesktopBar::ALIGN_BOTTOM); |
| 412 } |
| 413 return bottom; |
| 414 } |
| 415 |
| 416 void PanelManager::OnAutoHidingDesktopBarThicknessChanged() { |
| 417 AdjustWorkAreaForAutoHidingDesktopBars(); |
| 418 Rearrange(panels_.begin(), adjusted_work_area_.right()); |
| 419 } |
| 420 |
| 421 void PanelManager::OnAutoHidingDesktopBarVisibilityChanged( |
| 422 AutoHidingDesktopBar::Alignment alignment, |
| 423 AutoHidingDesktopBar::Visibility visibility) { |
| 424 if (delayed_titlebar_action_ == NO_ACTION) |
| 425 return; |
| 426 |
| 427 AutoHidingDesktopBar::Visibility expected_visibility = |
| 428 delayed_titlebar_action_ == BRING_UP ? AutoHidingDesktopBar::VISIBLE |
| 429 : AutoHidingDesktopBar::HIDDEN; |
| 430 if (visibility != expected_visibility) |
| 431 return; |
| 432 |
| 433 DoBringUpOrDownTitlebars(delayed_titlebar_action_ == BRING_UP); |
| 434 delayed_titlebar_action_ = NO_ACTION; |
| 435 } |
| 436 |
| 437 void PanelManager::Rearrange(Panels::iterator iter_to_start, |
| 438 int rightmost_position) { |
| 301 if (iter_to_start == panels_.end()) | 439 if (iter_to_start == panels_.end()) |
| 302 return; | 440 return; |
| 303 | 441 |
| 304 for (Panels::iterator iter = iter_to_start; iter != panels_.end(); ++iter) { | 442 for (Panels::iterator iter = iter_to_start; iter != panels_.end(); ++iter) { |
| 305 gfx::Rect new_bounds((*iter)->GetBounds()); | 443 Panel* panel = *iter; |
| 306 ComputeBoundsForNextPanel(&new_bounds, false); | 444 |
| 307 if (new_bounds != (*iter)->GetBounds()) | 445 gfx::Rect new_bounds(panel->GetBounds()); |
| 308 (*iter)->SetPanelBounds(new_bounds); | 446 new_bounds.set_x(rightmost_position - new_bounds.width()); |
| 447 new_bounds.set_y(adjusted_work_area_.bottom() - new_bounds.height()); |
| 448 if (new_bounds != panel->GetBounds()) |
| 449 panel->SetPanelBounds(new_bounds); |
| 450 |
| 451 rightmost_position = new_bounds.x() - kPanelsHorizontalSpacing; |
| 309 } | 452 } |
| 310 } | 453 } |
| 311 | 454 |
| 312 bool PanelManager::ComputeBoundsForNextPanel(gfx::Rect* bounds, | |
| 313 bool allow_size_change) { | |
| 314 int width = bounds->width(); | |
| 315 int height = bounds->height(); | |
| 316 | |
| 317 // Update the width and/or height to fit into our constraint. | |
| 318 if (allow_size_change) { | |
| 319 if (width == 0 && height == 0) { | |
| 320 width = kPanelDefaultWidthPixels; | |
| 321 height = kPanelDefaultHeightPixels; | |
| 322 } | |
| 323 | |
| 324 if (width < kPanelMinWidthPixels) | |
| 325 width = kPanelMinWidthPixels; | |
| 326 else if (width > max_width_) | |
| 327 width = max_width_; | |
| 328 | |
| 329 if (height < kPanelMinHeightPixels) | |
| 330 height = kPanelMinHeightPixels; | |
| 331 else if (height > max_height_) | |
| 332 height = max_height_; | |
| 333 } | |
| 334 | |
| 335 int x = current_x_ - width; | |
| 336 int y = bottom_edge_y_ - height; | |
| 337 | |
| 338 if (x < min_x_) | |
| 339 return false; | |
| 340 | |
| 341 current_x_ -= width + kPanelsHorizontalSpacing; | |
| 342 | |
| 343 bounds->SetRect(x, y, width, height); | |
| 344 return true; | |
| 345 } | |
| 346 | |
| 347 void PanelManager::RemoveAll() { | 455 void PanelManager::RemoveAll() { |
| 348 // This should not be called when we're in the process of dragging. | 456 // This should not be called when we're in the process of dragging. |
| 349 DCHECK(dragging_panel_index_ == kInvalidPanelIndex); | 457 DCHECK(dragging_panel_index_ == kInvalidPanelIndex); |
| 350 | 458 |
| 351 // Make a copy of the iterator as closing panels can modify the vector. | 459 // Make a copy of the iterator as closing panels can modify the vector. |
| 352 Panels panels_copy = panels_; | 460 Panels panels_copy = panels_; |
| 353 | 461 |
| 354 // Start from the bottom to avoid reshuffling. | 462 // Start from the bottom to avoid reshuffling. |
| 355 for (Panels::reverse_iterator iter = panels_copy.rbegin(); | 463 for (Panels::reverse_iterator iter = panels_copy.rbegin(); |
| 356 iter != panels_copy.rend(); ++iter) | 464 iter != panels_copy.rend(); ++iter) |
| 357 (*iter)->Close(); | 465 (*iter)->Close(); |
| 358 } | 466 } |
| 359 | 467 |
| 360 bool PanelManager::is_dragging_panel() const { | 468 bool PanelManager::is_dragging_panel() const { |
| 361 return dragging_panel_index_ != kInvalidPanelIndex; | 469 return dragging_panel_index_ != kInvalidPanelIndex; |
| 362 } | 470 } |
| OLD | NEW |