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 |