| 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 | 
|---|