| 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_strip.h" | 5 #include "chrome/browser/ui/panels/panel_strip.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "chrome/browser/ui/browser.h" | 12 #include "chrome/browser/ui/browser.h" |
| 13 #include "chrome/browser/ui/panels/panel_manager.h" | 13 #include "chrome/browser/ui/panels/panel_manager.h" |
| 14 #include "chrome/browser/ui/panels/panel_mouse_watcher.h" | 14 #include "chrome/browser/ui/panels/panel_mouse_watcher.h" |
| 15 #include "chrome/common/chrome_notification_types.h" | 15 #include "chrome/common/chrome_notification_types.h" |
| 16 #include "content/public/browser/notification_service.h" | 16 #include "content/public/browser/notification_service.h" |
| 17 #include "content/public/browser/notification_source.h" | 17 #include "content/public/browser/notification_source.h" |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 // Invalid panel index. | 20 // Invalid panel index. |
| 21 const size_t kInvalidPanelIndex = static_cast<size_t>(-1); | 21 const size_t kInvalidPanelIndex = static_cast<size_t>(-1); |
| 22 | 22 |
| 23 // Width to height ratio is used to compute the default width or height | 23 // Width to height ratio is used to compute the default width or height |
| 24 // when only one value is provided. | 24 // when only one value is provided. |
| 25 const double kPanelDefaultWidthToHeightRatio = 1.62; // golden ratio | 25 const double kPanelDefaultWidthToHeightRatio = 1.62; // golden ratio |
| 26 | 26 |
| 27 // Maxmium width of a panel is based on a factor of the entire panel strip. | 27 // Maxmium width of a panel is based on a factor of the entire panel strip. |
| 28 const double kPanelMaxWidthFactor = 0.35; | 28 const double kPanelMaxWidthFactor = 0.35; |
| 29 | 29 |
| 30 // New panels that cannot fit in the panel strip are moved to overflow |
| 31 // after a brief delay. |
| 32 const int kMoveNewPanelToOverflowDelayMilliseconds = 1500; // arbitrary |
| 33 |
| 30 // Occasionally some system, like Windows, might not bring up or down the bottom | 34 // Occasionally some system, like Windows, might not bring up or down the bottom |
| 31 // bar when the mouse enters or leaves the bottom screen area. This is the | 35 // bar when the mouse enters or leaves the bottom screen area. This is the |
| 32 // maximum time we will wait for the bottom bar visibility change notification. | 36 // maximum time we will wait for the bottom bar visibility change notification. |
| 33 // After the time expires, we bring up/down the titlebars as planned. | 37 // After the time expires, we bring up/down the titlebars as planned. |
| 34 const int kMaxMillisecondsWaitForBottomBarVisibilityChange = 1000; | 38 const int kMaxMillisecondsWaitForBottomBarVisibilityChange = 1000; |
| 35 | 39 |
| 36 // See usage below. | 40 // See usage below. |
| 37 #if defined(TOOLKIT_GTK) | 41 #if defined(TOOLKIT_GTK) |
| 38 const int kMillisecondsBeforeCollapsingFromTitleOnlyState = 2000; | 42 const int kMillisecondsBeforeCollapsingFromTitleOnlyState = 2000; |
| 39 #else | 43 #else |
| 40 const int kMillisecondsBeforeCollapsingFromTitleOnlyState = 0; | 44 const int kMillisecondsBeforeCollapsingFromTitleOnlyState = 0; |
| 41 #endif | 45 #endif |
| 42 } // namespace | 46 } // namespace |
| 43 | 47 |
| 44 // static | 48 // static |
| 45 const int PanelStrip::kPanelMinWidth = 100; | 49 const int PanelStrip::kPanelMinWidth = 100; |
| 46 const int PanelStrip::kPanelMinHeight = 20; | 50 const int PanelStrip::kPanelMinHeight = 20; |
| 47 | 51 |
| 48 PanelStrip::PanelStrip(PanelManager* panel_manager) | 52 PanelStrip::PanelStrip(PanelManager* panel_manager) |
| 49 : panel_manager_(panel_manager), | 53 : panel_manager_(panel_manager), |
| 50 minimized_panel_count_(0), | 54 minimized_panel_count_(0), |
| 51 are_titlebars_up_(false), | 55 are_titlebars_up_(false), |
| 52 dragging_panel_index_(kInvalidPanelIndex), | 56 dragging_panel_index_(kInvalidPanelIndex), |
| 53 dragging_panel_original_x_(0), | 57 dragging_panel_original_x_(0), |
| 54 delayed_titlebar_action_(NO_ACTION), | 58 delayed_titlebar_action_(NO_ACTION), |
| 55 remove_delays_for_testing_(false), | 59 remove_delays_for_testing_(false), |
| 56 titlebar_action_factory_(this) { | 60 titlebar_action_factory_(this), |
| 61 overflow_action_factory_(this) { |
| 57 } | 62 } |
| 58 | 63 |
| 59 PanelStrip::~PanelStrip() { | 64 PanelStrip::~PanelStrip() { |
| 60 DCHECK(panels_.empty()); | 65 DCHECK(panels_.empty()); |
| 61 DCHECK(panels_pending_to_remove_.empty()); | 66 DCHECK(panels_pending_to_remove_.empty()); |
| 62 DCHECK_EQ(0, minimized_panel_count_); | 67 DCHECK_EQ(0, minimized_panel_count_); |
| 63 } | 68 } |
| 64 | 69 |
| 65 void PanelStrip::SetBounds(const gfx::Rect bounds) { | 70 void PanelStrip::SetDisplayArea(const gfx::Rect& new_area) { |
| 66 if (strip_bounds_ == bounds) | 71 if (display_area_ == new_area) |
| 67 return; | 72 return; |
| 68 | 73 |
| 69 strip_bounds_ = bounds; | 74 gfx::Rect old_area = display_area_; |
| 70 Rearrange(panels_.begin(), StartingRightPosition()); | 75 display_area_ = new_area; |
| 76 |
| 77 if (panels_.empty() || new_area.width() == old_area.width()) |
| 78 return; |
| 79 |
| 80 if (new_area.width() < old_area.width()) |
| 81 Rearrange(); |
| 82 else |
| 83 MovePanelsFromOverflowIfNeeded(); |
| 71 } | 84 } |
| 72 | 85 |
| 73 void PanelStrip::AddPanel(Panel* panel) { | 86 void PanelStrip::AddPanel(Panel* panel) { |
| 74 if (panel->initialized()) | 87 if (panel->initialized()) |
| 75 AddExistingPanel(panel); | 88 AddExistingPanel(panel); |
| 76 else | 89 else |
| 77 AddNewPanel(panel); | 90 AddNewPanel(panel); |
| 78 panels_.push_back(panel); | 91 panels_.push_back(panel); |
| 79 } | 92 } |
| 80 | 93 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 106 else if (width > max_panel_width) | 119 else if (width > max_panel_width) |
| 107 width = max_panel_width; | 120 width = max_panel_width; |
| 108 | 121 |
| 109 if (height < kPanelMinHeight) | 122 if (height < kPanelMinHeight) |
| 110 height = kPanelMinHeight; | 123 height = kPanelMinHeight; |
| 111 else if (height > max_panel_height) | 124 else if (height > max_panel_height) |
| 112 height = max_panel_height; | 125 height = max_panel_height; |
| 113 panel->set_restored_size(gfx::Size(width, height)); | 126 panel->set_restored_size(gfx::Size(width, height)); |
| 114 | 127 |
| 115 // Layout the new panel. | 128 // Layout the new panel. |
| 116 int y = strip_bounds_.bottom() - height; | 129 int y = display_area_.bottom() - height; |
| 117 int x = GetRightMostAvailablePosition() - width; | 130 int x = GetRightMostAvailablePosition() - width; |
| 131 |
| 132 // Keep panel visible in the strip even if overlap would occur. |
| 133 // Panel is moved to overflow from the strip after a delay. |
| 134 if (x < display_area_.x()) { |
| 135 x = display_area_.x(); |
| 136 MessageLoop::current()->PostDelayedTask( |
| 137 FROM_HERE, |
| 138 base::Bind(&PanelStrip::MovePanelToOverflow, |
| 139 overflow_action_factory_.GetWeakPtr(), |
| 140 panel, |
| 141 true), // new panel |
| 142 kMoveNewPanelToOverflowDelayMilliseconds); |
| 143 } |
| 118 panel->Initialize(gfx::Rect(x, y, width, height)); | 144 panel->Initialize(gfx::Rect(x, y, width, height)); |
| 119 } | 145 } |
| 120 | 146 |
| 121 void PanelStrip::AddExistingPanel(Panel* panel) { | 147 void PanelStrip::AddExistingPanel(Panel* panel) { |
| 122 gfx::Size restored_size = panel->restored_size(); | 148 gfx::Size restored_size = panel->restored_size(); |
| 123 int height = restored_size.height(); | 149 int height = restored_size.height(); |
| 124 int width = restored_size.width(); | 150 int width = restored_size.width(); |
| 125 int x = GetRightMostAvailablePosition() - width; | 151 int x; |
| 126 int y = strip_bounds_.bottom() - height; | 152 while ((x = GetRightMostAvailablePosition() - width) < display_area_.x()) { |
| 153 DCHECK(!panels_.empty()); |
| 154 MovePanelToOverflow(panels_.back(), false); |
| 155 } |
| 156 int y = display_area_.bottom() - height; |
| 127 panel->SetPanelBounds(gfx::Rect(x, y, width, height)); | 157 panel->SetPanelBounds(gfx::Rect(x, y, width, height)); |
| 128 } | 158 } |
| 129 | 159 |
| 130 int PanelStrip::GetMaxPanelWidth() const { | 160 int PanelStrip::GetMaxPanelWidth() const { |
| 131 return static_cast<int>(strip_bounds_.width() * kPanelMaxWidthFactor); | 161 return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor); |
| 132 } | 162 } |
| 133 | 163 |
| 134 int PanelStrip::GetMaxPanelHeight() const { | 164 int PanelStrip::GetMaxPanelHeight() const { |
| 135 return strip_bounds_.height(); | 165 return display_area_.height(); |
| 136 } | 166 } |
| 137 | 167 |
| 138 int PanelStrip::StartingRightPosition() const { | 168 int PanelStrip::StartingRightPosition() const { |
| 139 return strip_bounds_.right(); | 169 return display_area_.right(); |
| 140 } | 170 } |
| 141 | 171 |
| 142 int PanelStrip::GetRightMostAvailablePosition() const { | 172 int PanelStrip::GetRightMostAvailablePosition() const { |
| 143 return panels_.empty() ? StartingRightPosition() : | 173 return panels_.empty() ? StartingRightPosition() : |
| 144 (panels_.back()->GetBounds().x() - kPanelsHorizontalSpacing); | 174 (panels_.back()->GetBounds().x() - kPanelsHorizontalSpacing); |
| 145 } | 175 } |
| 146 | 176 |
| 147 bool PanelStrip::Remove(Panel* panel) { | 177 bool PanelStrip::Remove(Panel* panel) { |
| 148 if (find(panels_.begin(), panels_.end(), panel) == panels_.end()) | 178 if (find(panels_.begin(), panels_.end(), panel) == panels_.end()) |
| 149 return false; | 179 return false; |
| 150 | 180 |
| 151 // If we're in the process of dragging, delay the removal. | 181 // If we're in the process of dragging, delay the removal. |
| 152 if (dragging_panel_index_ != kInvalidPanelIndex) { | 182 if (dragging_panel_index_ != kInvalidPanelIndex) { |
| 153 panels_pending_to_remove_.push_back(panel); | 183 panels_pending_to_remove_.push_back(panel); |
| 154 return true; | 184 return true; |
| 155 } | 185 } |
| 156 | 186 |
| 157 DoRemove(panel); | 187 DoRemove(panel); |
| 188 Rearrange(); |
| 158 return true; | 189 return true; |
| 159 } | 190 } |
| 160 | 191 |
| 161 void PanelStrip::DelayedRemove() { | 192 void PanelStrip::DelayedRemove() { |
| 162 for (size_t i = 0; i < panels_pending_to_remove_.size(); ++i) | 193 for (size_t i = 0; i < panels_pending_to_remove_.size(); ++i) |
| 163 DoRemove(panels_pending_to_remove_[i]); | 194 DoRemove(panels_pending_to_remove_[i]); |
| 164 panels_pending_to_remove_.clear(); | 195 panels_pending_to_remove_.clear(); |
| 196 Rearrange(); |
| 165 } | 197 } |
| 166 | 198 |
| 167 void PanelStrip::DoRemove(Panel* panel) { | 199 bool PanelStrip::DoRemove(Panel* panel) { |
| 168 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); | 200 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); |
| 169 if (iter == panels_.end()) | 201 if (iter == panels_.end()) |
| 170 return; | 202 return false; |
| 171 | 203 |
| 172 if (panel->expansion_state() != Panel::EXPANDED) | 204 if (panel->expansion_state() != Panel::EXPANDED) |
| 173 DecrementMinimizedPanels(); | 205 DecrementMinimizedPanels(); |
| 174 | 206 |
| 175 gfx::Rect bounds = (*iter)->GetBounds(); | 207 panels_.erase(iter); |
| 176 Rearrange(panels_.erase(iter), bounds.right()); | 208 return true; |
| 177 panel_manager_->OnPanelRemoved(panel); | |
| 178 } | 209 } |
| 179 | 210 |
| 180 void PanelStrip::StartDragging(Panel* panel) { | 211 void PanelStrip::StartDragging(Panel* panel) { |
| 181 for (size_t i = 0; i < panels_.size(); ++i) { | 212 for (size_t i = 0; i < panels_.size(); ++i) { |
| 182 if (panels_[i] == panel) { | 213 if (panels_[i] == panel) { |
| 183 dragging_panel_index_ = i; | 214 dragging_panel_index_ = i; |
| 184 dragging_panel_bounds_ = panel->GetBounds(); | 215 dragging_panel_bounds_ = panel->GetBounds(); |
| 185 dragging_panel_original_x_ = dragging_panel_bounds_.x(); | 216 dragging_panel_original_x_ = dragging_panel_bounds_.x(); |
| 186 break; | 217 break; |
| 187 } | 218 } |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 gfx::Rect bounds = panel->GetBounds(); | 375 gfx::Rect bounds = panel->GetBounds(); |
| 345 | 376 |
| 346 // The panel width: | 377 // The panel width: |
| 347 // * cannot grow or shrink to go beyond [min_width, max_width] | 378 // * cannot grow or shrink to go beyond [min_width, max_width] |
| 348 int new_width = preferred_window_size.width(); | 379 int new_width = preferred_window_size.width(); |
| 349 if (new_width > panel->max_size().width()) | 380 if (new_width > panel->max_size().width()) |
| 350 new_width = panel->max_size().width(); | 381 new_width = panel->max_size().width(); |
| 351 if (new_width < panel->min_size().width()) | 382 if (new_width < panel->min_size().width()) |
| 352 new_width = panel->min_size().width(); | 383 new_width = panel->min_size().width(); |
| 353 | 384 |
| 354 if (new_width != bounds.width()) { | |
| 355 int delta = bounds.width() - new_width; | |
| 356 bounds.set_x(bounds.x() + delta); | |
| 357 bounds.set_width(new_width); | |
| 358 | |
| 359 // Reposition all the panels on the left. | |
| 360 int panel_index = -1; | |
| 361 for (int i = 0; i < static_cast<int>(panels_.size()); ++i) { | |
| 362 if (panels_[i] == panel) { | |
| 363 panel_index = i; | |
| 364 break; | |
| 365 } | |
| 366 } | |
| 367 DCHECK(panel_index >= 0); | |
| 368 for (int i = static_cast<int>(panels_.size()) -1; i > panel_index; | |
| 369 --i) { | |
| 370 gfx::Rect this_bounds = panels_[i]->GetBounds(); | |
| 371 this_bounds.set_x(this_bounds.x() + delta); | |
| 372 panels_[i]->SetPanelBounds(this_bounds); | |
| 373 } | |
| 374 } | |
| 375 | |
| 376 // The panel height: | 385 // The panel height: |
| 377 // * cannot grow or shrink to go beyond [min_height, max_height] | 386 // * cannot grow or shrink to go beyond [min_height, max_height] |
| 378 int new_height = preferred_window_size.height(); | 387 int new_height = preferred_window_size.height(); |
| 379 if (new_height > panel->max_size().height()) | 388 if (new_height > panel->max_size().height()) |
| 380 new_height = panel->max_size().height(); | 389 new_height = panel->max_size().height(); |
| 381 if (new_height < panel->min_size().height()) | 390 if (new_height < panel->min_size().height()) |
| 382 new_height = panel->min_size().height(); | 391 new_height = panel->min_size().height(); |
| 383 | 392 |
| 393 // Update restored size. |
| 394 gfx::Size new_size(new_width, new_height); |
| 395 if (new_size != panel->restored_size()) |
| 396 panel->set_restored_size(preferred_window_size); |
| 397 |
| 384 // Only need to adjust bounds height when panel is expanded. | 398 // Only need to adjust bounds height when panel is expanded. |
| 385 gfx::Size restored_size = panel->restored_size(); | 399 if (new_height != bounds.height() && |
| 386 if (new_height != restored_size.height() && | |
| 387 panel->expansion_state() == Panel::EXPANDED) { | 400 panel->expansion_state() == Panel::EXPANDED) { |
| 388 bounds.set_y(bounds.y() - new_height + bounds.height()); | 401 bounds.set_y(bounds.bottom() - new_height); |
| 389 bounds.set_height(new_height); | 402 bounds.set_height(new_height); |
| 390 } | 403 } |
| 391 | 404 |
| 392 gfx::Size new_size = gfx::Size(new_width, new_height); | 405 // Adjust bounds width. |
| 393 if (new_size != restored_size) | 406 int delta_x = bounds.width() - new_width; |
| 394 panel->set_restored_size(new_size); | 407 if (delta_x != 0) { |
| 408 bounds.set_width(new_width); |
| 409 bounds.set_x(bounds.x() + delta_x); |
| 410 } |
| 395 | 411 |
| 396 panel->SetPanelBounds(bounds); | 412 panel->SetPanelBounds(bounds); |
| 413 |
| 414 // Only need to rearrange if panel's width changed. |
| 415 if (delta_x != 0) |
| 416 Rearrange(); |
| 397 } | 417 } |
| 398 | 418 |
| 399 bool PanelStrip::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { | 419 bool PanelStrip::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { |
| 400 // We should always bring up the titlebar if the mouse is over the | 420 // We should always bring up the titlebar if the mouse is over the |
| 401 // visible auto-hiding bottom bar. | 421 // visible auto-hiding bottom bar. |
| 402 AutoHidingDesktopBar* desktop_bar = panel_manager_->auto_hiding_desktop_bar(); | 422 AutoHidingDesktopBar* desktop_bar = panel_manager_->auto_hiding_desktop_bar(); |
| 403 if (desktop_bar->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM) && | 423 if (desktop_bar->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM) && |
| 404 desktop_bar->GetVisibility(AutoHidingDesktopBar::ALIGN_BOTTOM) == | 424 desktop_bar->GetVisibility(AutoHidingDesktopBar::ALIGN_BOTTOM) == |
| 405 AutoHidingDesktopBar::VISIBLE && | 425 AutoHidingDesktopBar::VISIBLE && |
| 406 mouse_y >= strip_bounds_.bottom()) | 426 mouse_y >= display_area_.bottom()) |
| 407 return true; | 427 return true; |
| 408 | 428 |
| 409 for (Panels::const_iterator iter = panels_.begin(); | 429 for (Panels::const_iterator iter = panels_.begin(); |
| 410 iter != panels_.end(); ++iter) { | 430 iter != panels_.end(); ++iter) { |
| 411 if ((*iter)->ShouldBringUpTitlebar(mouse_x, mouse_y)) | 431 if ((*iter)->ShouldBringUpTitlebar(mouse_x, mouse_y)) |
| 412 return true; | 432 return true; |
| 413 } | 433 } |
| 414 return false; | 434 return false; |
| 415 } | 435 } |
| 416 | 436 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 panel->SetExpansionState(Panel::TITLE_ONLY); | 524 panel->SetExpansionState(Panel::TITLE_ONLY); |
| 505 } else { | 525 } else { |
| 506 if (panel->expansion_state() == Panel::TITLE_ONLY) | 526 if (panel->expansion_state() == Panel::TITLE_ONLY) |
| 507 panel->SetExpansionState(Panel::MINIMIZED); | 527 panel->SetExpansionState(Panel::MINIMIZED); |
| 508 } | 528 } |
| 509 } | 529 } |
| 510 } | 530 } |
| 511 | 531 |
| 512 int PanelStrip::GetBottomPositionForExpansionState( | 532 int PanelStrip::GetBottomPositionForExpansionState( |
| 513 Panel::ExpansionState expansion_state) const { | 533 Panel::ExpansionState expansion_state) const { |
| 514 int bottom = strip_bounds_.bottom(); | 534 int bottom = display_area_.bottom(); |
| 515 // If there is an auto-hiding desktop bar aligned to the bottom edge, we need | 535 // If there is an auto-hiding desktop bar aligned to the bottom edge, we need |
| 516 // to move the title-only panel above the auto-hiding desktop bar. | 536 // to move the title-only panel above the auto-hiding desktop bar. |
| 517 AutoHidingDesktopBar* desktop_bar = panel_manager_->auto_hiding_desktop_bar(); | 537 AutoHidingDesktopBar* desktop_bar = panel_manager_->auto_hiding_desktop_bar(); |
| 518 if (expansion_state == Panel::TITLE_ONLY && | 538 if (expansion_state == Panel::TITLE_ONLY && |
| 519 desktop_bar->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM)) { | 539 desktop_bar->IsEnabled(AutoHidingDesktopBar::ALIGN_BOTTOM)) { |
| 520 bottom -= desktop_bar->GetThickness(AutoHidingDesktopBar::ALIGN_BOTTOM); | 540 bottom -= desktop_bar->GetThickness(AutoHidingDesktopBar::ALIGN_BOTTOM); |
| 521 } | 541 } |
| 522 | 542 |
| 523 return bottom; | 543 return bottom; |
| 524 } | 544 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 538 AutoHidingDesktopBar::Visibility expected_visibility = | 558 AutoHidingDesktopBar::Visibility expected_visibility = |
| 539 delayed_titlebar_action_ == BRING_UP ? AutoHidingDesktopBar::VISIBLE | 559 delayed_titlebar_action_ == BRING_UP ? AutoHidingDesktopBar::VISIBLE |
| 540 : AutoHidingDesktopBar::HIDDEN; | 560 : AutoHidingDesktopBar::HIDDEN; |
| 541 if (visibility != expected_visibility) | 561 if (visibility != expected_visibility) |
| 542 return; | 562 return; |
| 543 | 563 |
| 544 DoBringUpOrDownTitlebars(delayed_titlebar_action_ == BRING_UP); | 564 DoBringUpOrDownTitlebars(delayed_titlebar_action_ == BRING_UP); |
| 545 delayed_titlebar_action_ = NO_ACTION; | 565 delayed_titlebar_action_ = NO_ACTION; |
| 546 } | 566 } |
| 547 | 567 |
| 548 void PanelStrip::Rearrange(Panels::iterator iter_to_start, | 568 void PanelStrip::Rearrange() { |
| 549 int rightmost_position) { | 569 int rightmost_position = StartingRightPosition(); |
| 550 for (Panels::iterator iter = iter_to_start; iter != panels_.end(); ++iter) { | 570 |
| 551 Panel* panel = *iter; | 571 size_t panel_index = 0; |
| 572 for (; panel_index < panels_.size(); ++panel_index) { |
| 573 Panel* panel = panels_[panel_index]; |
| 552 gfx::Rect new_bounds(panel->GetBounds()); | 574 gfx::Rect new_bounds(panel->GetBounds()); |
| 575 int x = rightmost_position - new_bounds.width(); |
| 576 |
| 577 if (x < display_area_.x()) { |
| 578 MovePanelsToOverflow(panel_index); |
| 579 break; |
| 580 } |
| 581 |
| 553 new_bounds.set_x(rightmost_position - new_bounds.width()); | 582 new_bounds.set_x(rightmost_position - new_bounds.width()); |
| 554 new_bounds.set_y( | 583 new_bounds.set_y( |
| 555 GetBottomPositionForExpansionState(panel->expansion_state()) - | 584 GetBottomPositionForExpansionState(panel->expansion_state()) - |
| 556 new_bounds.height()); | 585 new_bounds.height()); |
| 557 panel->SetPanelBounds(new_bounds); | 586 panel->SetPanelBounds(new_bounds); |
| 558 | 587 |
| 559 rightmost_position = new_bounds.x() - kPanelsHorizontalSpacing; | 588 rightmost_position = new_bounds.x() - kPanelsHorizontalSpacing; |
| 560 } | 589 } |
| 590 |
| 591 if (panel_index == panels_.size()) |
| 592 MovePanelsFromOverflowIfNeeded(); |
| 593 } |
| 594 |
| 595 void PanelStrip::MovePanelsToOverflow(size_t overflow_point) { |
| 596 DCHECK(overflow_point >= 0); |
| 597 // Move panels in reverse to maintain their order. |
| 598 for (size_t i = panels_.size() - 1; i >= overflow_point; --i) |
| 599 MovePanelToOverflow(panels_[i], false); |
| 600 } |
| 601 |
| 602 void PanelStrip::MovePanelToOverflow(Panel* panel, bool is_new) { |
| 603 if (!DoRemove(panel)) |
| 604 return; |
| 605 |
| 606 // TODO(jianli): Replace with the real code using overflow strip. |
| 607 // panel_manager_->panel_overflow_strip()->AddPanel(panel, is_new); |
| 608 } |
| 609 |
| 610 void PanelStrip::MovePanelsFromOverflowIfNeeded() { |
| 611 // TODO(jianli): Replace with the real code using overflow strip. |
| 612 // PanelOverflowStrip* overflow = panel_manager_->panel_overflow_strip(); |
| 613 // Panel* candidate; |
| 614 // while (candidate = overflow->FirstPanel() && |
| 615 // GetRightMostAvailablePosition - |
| 616 // candidate->GetRestoredSize().width() >= display_area_.x()) { |
| 617 // overflow->Remove(candidate); |
| 618 // AddPanel(candidate); |
| 619 // } |
| 561 } | 620 } |
| 562 | 621 |
| 563 void PanelStrip::RemoveAll() { | 622 void PanelStrip::RemoveAll() { |
| 564 // This should not be called when we're in the process of dragging. | 623 // This should not be called when we're in the process of dragging. |
| 565 DCHECK(dragging_panel_index_ == kInvalidPanelIndex); | 624 DCHECK(dragging_panel_index_ == kInvalidPanelIndex); |
| 566 | 625 |
| 567 // Make a copy of the iterator as closing panels can modify the vector. | 626 // Make a copy of the iterator as closing panels can modify the vector. |
| 568 Panels panels_copy = panels_; | 627 Panels panels_copy = panels_; |
| 569 | 628 |
| 570 // Start from the bottom to avoid reshuffling. | 629 // Start from the bottom to avoid reshuffling. |
| 571 for (Panels::reverse_iterator iter = panels_copy.rbegin(); | 630 for (Panels::reverse_iterator iter = panels_copy.rbegin(); |
| 572 iter != panels_copy.rend(); ++iter) | 631 iter != panels_copy.rend(); ++iter) |
| 573 (*iter)->Close(); | 632 (*iter)->Close(); |
| 574 } | 633 } |
| 575 | 634 |
| 576 bool PanelStrip::is_dragging_panel() const { | 635 bool PanelStrip::is_dragging_panel() const { |
| 577 return dragging_panel_index_ != kInvalidPanelIndex; | 636 return dragging_panel_index_ != kInvalidPanelIndex; |
| 578 } | 637 } |
| OLD | NEW |