Chromium Code Reviews| Index: chrome/browser/ui/panels/docked_panel_strip.cc |
| diff --git a/chrome/browser/ui/panels/docked_panel_strip.cc b/chrome/browser/ui/panels/docked_panel_strip.cc |
| index d4cd227cac19fd76788d5eb3f63be9239b8b3f14..15d1f5129de78036c0f2331f29d45bd131fde9cb 100644 |
| --- a/chrome/browser/ui/panels/docked_panel_strip.cc |
| +++ b/chrome/browser/ui/panels/docked_panel_strip.cc |
| @@ -12,6 +12,7 @@ |
| #include "base/message_loop.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/panels/overflow_panel_strip.h" |
| +#include "chrome/browser/ui/panels/panel_drag_controller.h" |
| #include "chrome/browser/ui/panels/panel_manager.h" |
| #include "chrome/browser/ui/panels/panel_mouse_watcher.h" |
| #include "chrome/common/chrome_notification_types.h" |
| @@ -60,10 +61,10 @@ DockedPanelStrip::DockedPanelStrip(PanelManager* panel_manager) |
| minimized_panel_count_(0), |
| are_titlebars_up_(false), |
| disable_layout_refresh_(false), |
| + panel_to_restore_after_on_drag_cancelled_(NULL), |
| delayed_titlebar_action_(NO_ACTION), |
| titlebar_action_factory_(this) { |
| - dragging_panel_current_iterator_ = dragging_panel_original_iterator_ = |
| - panels_.end(); |
| + dragging_panel_current_iterator_ = panels_.end(); |
| } |
| DockedPanelStrip::~DockedPanelStrip() { |
| @@ -100,16 +101,10 @@ void DockedPanelStrip::AddPanel(Panel* panel) { |
| int width = restored_size.width(); |
| if (panel->initialized()) { |
| - // Bump panels in the strip to make room for this panel. |
| - // Prevent layout refresh when panel is removed from this strip. |
| - disable_layout_refresh_ = true; |
| - PanelStrip* overflow_strip = panel_manager_->overflow_strip(); |
| - int x; |
| - while ((x = GetRightMostAvailablePosition() - width) < display_area_.x()) { |
| - DCHECK(!panels_.empty()); |
| - panels_.back()->MoveToStrip(overflow_strip); |
| - } |
| - disable_layout_refresh_ = false; |
| + // Make sure we have sufficient space for this panel. We might bump |
| + // panels in the strip to make room for this panel. |
| + EnsureEnoughSpaceForPanel(width); |
| + int x = GetRightMostAvailablePosition() - width; |
| Panel::ExpansionState expansion_state_to_restore; |
| if (panel->expansion_state() == Panel::EXPANDED) { |
| @@ -186,6 +181,46 @@ void DockedPanelStrip::AddPanel(Panel* panel) { |
| panels_.push_back(panel); |
| } |
| +void DockedPanelStrip::AddPanelAtPosition(Panel* panel, |
| + const gfx::Point& position) { |
| + // First, make sure we have sufficient space for this panel. We might bump |
| + // panels in the strip to make room for this panel. |
| + EnsureEnoughSpaceForPanel(panel->GetBounds().width()); |
| + |
| + // Set panel properties for this strip. |
|
jennb
2012/03/01 00:33:38
Wish this method and AddPanels() could be consolid
jianli
2012/03/02 22:42:43
I agree but it will involve quite a bit of refacto
|
| + panel->SetAppIconVisibility(true); |
| + |
| + // Then, find and insert this panel to the right position. |
| + int x = position.x(); |
| + Panels::iterator iter = panels_.begin(); |
| + for (; iter != panels_.end(); ++iter) { |
| + Panel* current_panel = *iter; |
| + gfx::Rect current_bounds = current_panel->GetBounds(); |
| + if (x > current_bounds.x()) |
| + break; |
| + } |
| + panels_.insert(iter, panel); |
| + |
| + gfx::Rect new_bounds(panel->GetBounds()); |
|
jennb
2012/03/01 00:33:38
Won't refresh layout update the panel bounds corre
jianli
2012/03/02 22:42:43
RefreshLayout will not update the dragging panel.
|
| + new_bounds.set_origin(position); |
| + panel->SetPanelBounds(new_bounds); |
| + |
| + // This will automatically update all affected panels due to the insertion. |
| + RefreshLayout(); |
| +} |
| + |
| +void DockedPanelStrip::EnsureEnoughSpaceForPanel(int width) { |
| + // Prevent layout refresh when panel is removed from this strip. |
| + disable_layout_refresh_ = true; |
| + PanelStrip* overflow_strip = panel_manager_->overflow_strip(); |
| + int x; |
| + while ((x = GetRightMostAvailablePosition() - width) < display_area_.x()) { |
| + DCHECK(!panels_.empty()); |
| + panels_.back()->MoveToStrip(overflow_strip); |
| + } |
| + disable_layout_refresh_ = false; |
| +} |
| + |
| int DockedPanelStrip::GetMaxPanelWidth() const { |
| return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor); |
| } |
| @@ -217,26 +252,19 @@ bool DockedPanelStrip::RemovePanel(Panel* panel) { |
| DecrementMinimizedPanels(); |
| // Removing an element from the list will invalidate the iterator that refers |
| - // to it. So we need to check if the dragging panel iterators are affected. |
| - bool update_original_dragging_iterator_after_erase = false; |
| - if (dragging_panel_original_iterator_ != panels_.end()) { |
| - if (dragging_panel_current_iterator_ == iter) { |
| - // If the dragging panel is being removed, set both dragging iterators to |
| - // the end of the list. |
| - dragging_panel_current_iterator_ = dragging_panel_original_iterator_ = |
| - panels_.end(); |
| - } else if (dragging_panel_original_iterator_ == iter) { |
| - // If |dragging_panel_original_iterator_| refers to the element being |
| - // removed, set the flag so that the iterator can be updated to next |
| - // element. |
| - update_original_dragging_iterator_after_erase = true; |
| - } |
| - } |
| + // to it. If the dragging panel is being removed, set the dragging iterator to |
| + // the end of the list. |
| + if (dragging_panel_current_iterator_ == iter) |
| + dragging_panel_current_iterator_ = panels_.end(); |
| iter = panels_.erase(iter); |
| - if (update_original_dragging_iterator_after_erase) |
| - dragging_panel_original_iterator_ = iter; |
| + // If |panel_to_restore_after_on_drag_cancelled_| is removed, update it to |
| + // the next panel after the panel being removed. |
| + if (panel == panel_to_restore_after_on_drag_cancelled_) { |
| + panel_to_restore_after_on_drag_cancelled_ = |
| + (iter == panels_.end()) ? NULL : *iter; |
| + } |
| if (!disable_layout_refresh_) |
| RefreshLayout(); |
| @@ -255,15 +283,22 @@ bool DockedPanelStrip::CanDragPanel(const Panel* panel) const { |
| } |
| Panel* DockedPanelStrip::dragging_panel() const { |
| - return dragging_panel_current_iterator_ == panels_.end() ? NULL : |
| - *dragging_panel_current_iterator_; |
| + Panel* dragging_panel = panel_manager_->drag_controller()->dragging_panel(); |
| + return (dragging_panel && dragging_panel->panel_strip() == this) ? |
| + dragging_panel : NULL; |
| } |
| void DockedPanelStrip::StartDraggingPanel(Panel* panel) { |
| dragging_panel_current_iterator_ = |
| find(panels_.begin(), panels_.end(), panel); |
| DCHECK(dragging_panel_current_iterator_ != panels_.end()); |
| - dragging_panel_original_iterator_ = dragging_panel_current_iterator_; |
| + |
| + // Remember the panel to restore after. We only need to do it once when the |
| + // dragging panel does not leave the docked strip. |
| + if (!panel_manager_->drag_controller()->has_dragged_to_other_strip()) { |
| + panel_to_restore_after_on_drag_cancelled_ = |
| + GetNextPanel(dragging_panel_current_iterator_); |
| + } |
| } |
| void DockedPanelStrip::DragPanel(Panel* panel, int delta_x, int delta_y) { |
| @@ -341,35 +376,26 @@ void DockedPanelStrip::DragRight(Panel* dragging_panel) { |
| void DockedPanelStrip::EndDraggingPanel(Panel* panel, bool cancelled) { |
| if (cancelled) { |
| - if (dragging_panel_current_iterator_ != dragging_panel_original_iterator_) { |
| - // Find out if the dragging panel should be moved toward the end/beginning |
| - // of the list. |
| - bool move_towards_end_of_list = true; |
| - for (Panels::iterator iter = dragging_panel_original_iterator_; |
| - iter != panels_.end(); ++iter) { |
| - if (iter == dragging_panel_current_iterator_) { |
| - move_towards_end_of_list = false; |
| - break; |
| - } |
| - } |
| - |
| - // Move the dragging panel back to its original position by swapping it |
| - // with its adjacent element until it reach its original position. |
| - while (dragging_panel_current_iterator_ != |
| - dragging_panel_original_iterator_) { |
| - Panels::iterator next_iter = dragging_panel_current_iterator_; |
| - if (move_towards_end_of_list) |
| - ++next_iter; |
| - else |
| - --next_iter; |
| - iter_swap(dragging_panel_current_iterator_, next_iter); |
| - dragging_panel_current_iterator_ = next_iter; |
| + Panels::iterator next_iter = dragging_panel_current_iterator_; |
| + ++next_iter; |
| + if (panel_to_restore_after_on_drag_cancelled_ != |
| + GetNextPanel(dragging_panel_current_iterator_)) { |
| + // Remove the dragging panel from current position. |
| + panels_.erase(dragging_panel_current_iterator_); |
| + |
| + // Insert the dragging panel to the restore position. |
| + if (panel_to_restore_after_on_drag_cancelled_) { |
| + Panels::iterator iter_to_restore_after = std::find(panels_.begin(), |
| + panels_.end(), panel_to_restore_after_on_drag_cancelled_); |
| + DCHECK(iter_to_restore_after != panels_.end()); |
| + panels_.insert(iter_to_restore_after, panel); |
| + } else { |
| + panels_.push_back(panel); |
| } |
| } |
| } |
| - dragging_panel_current_iterator_ = dragging_panel_original_iterator_ = |
| - panels_.end(); |
| + dragging_panel_current_iterator_ = panels_.end(); |
| RefreshLayout(); |
| } |
| @@ -754,3 +780,10 @@ void DockedPanelStrip::CloseAll() { |
| iter != panels_copy.rend(); ++iter) |
| (*iter)->Close(); |
| } |
| + |
| +Panel* DockedPanelStrip::GetNextPanel(const Panels::iterator& iter) const { |
| + DCHECK(iter != panels_.end()); |
| + Panels::iterator next_iter = iter; |
| + ++next_iter; |
| + return (next_iter == panels_.end()) ? NULL : *next_iter; |
| +} |