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..d3b6e167c612ad3c32eb09fccd2a1481ca3acd3d 100644 |
| --- a/chrome/browser/ui/panels/docked_panel_strip.cc |
| +++ b/chrome/browser/ui/panels/docked_panel_strip.cc |
| @@ -62,8 +62,7 @@ DockedPanelStrip::DockedPanelStrip(PanelManager* panel_manager) |
| disable_layout_refresh_(false), |
| 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 +99,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. |
| + EnsureAvailableSpace(width); |
| + int x = GetRightMostAvailablePosition() - width; |
| Panel::ExpansionState expansion_state_to_restore; |
| if (panel->expansion_state() == Panel::EXPANDED) { |
| @@ -177,13 +170,31 @@ void DockedPanelStrip::AddPanel(Panel* panel) { |
| panel->Initialize(gfx::Rect(x, y, width, height)); |
| } |
| - // Set panel properties for this strip. |
| + // Insert the panel to the end. |
| + InsertPanelToCollection(panel, panels_.end()); |
|
jennb
2012/03/03 02:19:33
Don't refactor out the insertion logic as no other
jianli
2012/03/07 19:14:31
Done. Added OnPanelAdded.
|
| +} |
| + |
| +void DockedPanelStrip::InsertPanelToCollection( |
| + Panel* panel, Panels::iterator position) { |
| panel->SetAppIconVisibility(true); |
| + panel->SetAlwaysOnTop(true); |
| if (panel->has_temporary_layout()) |
| panels_in_temporary_layout_.insert(panel); |
| else |
| - panels_.push_back(panel); |
| + panels_.insert(position, panel); |
| +} |
| + |
| +void DockedPanelStrip::EnsureAvailableSpace(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 { |
| @@ -217,26 +228,20 @@ 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; |
| + // Update the saved panel placement if needed. This is because we might remove |
| + // |saved_panel_placement_.panel_to_place_before_|. |
| + if (saved_panel_placement_.panel && |
| + saved_panel_placement_.panel_to_place_before_ == panel) { |
| + saved_panel_placement_.panel_to_place_before_ = |
| + (iter == panels_.end()) ? NULL : *iter; |
| + } |
| if (!disable_layout_refresh_) |
| RefreshLayout(); |
| @@ -249,6 +254,59 @@ bool DockedPanelStrip::CanShowPanelAsActive(const Panel* panel) const { |
| return !panel->has_temporary_layout(); |
| } |
| +void DockedPanelStrip::SavePanelPlacement(Panel* panel) { |
| + DCHECK(!saved_panel_placement_.panel); |
| + |
| + saved_panel_placement_.panel = panel; |
| + |
| + // To recover panel to its original placement, we only need to track the panel |
| + // that is placed after it. |
| + Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); |
| + DCHECK(iter != panels_.end()); |
| + ++iter; |
| + saved_panel_placement_.panel_to_place_before_ = |
| + (iter == panels_.end()) ? NULL : *iter; |
| +} |
| + |
| +void DockedPanelStrip::LoadSavedPanelPlacement() { |
| + DCHECK(saved_panel_placement_.panel); |
| + |
| + Panel* panel = saved_panel_placement_.panel; |
| + saved_panel_placement_.panel = NULL; |
|
jennb
2012/03/03 02:19:33
leave it and call Discard at end of this method.
jianli
2012/03/07 19:14:31
Done.
|
| + |
| + // Find next panel after this panel. |
| + Panels::iterator iter = std::find(panels_.begin(), panels_.end(), panel); |
| + DCHECK(iter != panels_.end()); |
| + Panels::iterator next_iter = iter; |
| + next_iter++; |
| + Panel* next_panel = (next_iter == panels_.end()) ? NULL : *iter; |
| + |
| + // If this panel is already in the right position, nothing to do. |
| + if (next_panel == saved_panel_placement_.panel_to_place_before_) |
| + return; |
| + |
| + // Remove this panel from its current position. |
| + panels_.erase(iter); |
| + |
| + // Insert this panel into its previous position. |
| + if (saved_panel_placement_.panel_to_place_before_) { |
| + Panels::iterator iter_to_insert_before = std::find(panels_.begin(), |
| + panels_.end(), saved_panel_placement_.panel_to_place_before_); |
| + DCHECK(iter_to_insert_before != panels_.end()); |
| + panels_.insert(iter_to_insert_before, panel); |
| + } else { |
| + panels_.push_back(panel); |
| + } |
| + |
| + // This will automatically update all affected panels due to the insertion. |
| + RefreshLayout(); |
| +} |
| + |
| +void DockedPanelStrip::DiscardSavedPanelPlacement() { |
| + DCHECK(saved_panel_placement_.panel); |
| + saved_panel_placement_.panel = NULL; |
| +} |
| + |
| bool DockedPanelStrip::CanDragPanel(const Panel* panel) const { |
| // Only the panels having temporary layout can't be dragged. |
| return !panel->has_temporary_layout(); |
| @@ -259,14 +317,16 @@ Panel* DockedPanelStrip::dragging_panel() const { |
| *dragging_panel_current_iterator_; |
| } |
| -void DockedPanelStrip::StartDraggingPanel(Panel* panel) { |
| +void DockedPanelStrip::StartDraggingPanelLocally(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_; |
| } |
| -void DockedPanelStrip::DragPanel(Panel* panel, int delta_x, int delta_y) { |
| +void DockedPanelStrip::DragPanelLocally(Panel* panel, |
| + int delta_x, |
| + int delta_y) { |
| + DCHECK_EQ(dragging_panel(), panel); |
| if (!delta_x) |
| return; |
| @@ -339,38 +399,41 @@ 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; |
| - } |
| - } |
| +void DockedPanelStrip::EndDraggingPanelLocally(Panel* panel, bool cancelled) { |
| + DCHECK_EQ(dragging_panel(), panel); |
| - // 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; |
| - } |
| - } |
| + dragging_panel_current_iterator_ = panels_.end(); |
| + |
| + // If the drag is cancelled, we don't want to move the dragging panel to the |
|
jennb
2012/03/03 02:19:33
Maybe explain a bit about what is expected to happ
jianli
2012/03/07 19:14:31
Done.
|
| + // finalized position. |
| + if (!cancelled) |
| + RefreshLayout(); |
| +} |
| + |
| +void DockedPanelStrip::AddDraggingPanel(Panel* panel, |
| + const gfx::Point& position) { |
| + DCHECK_NE(this, panel->panel_strip()); |
| + panel->set_panel_strip(this); |
| + |
| + gfx::Rect new_bounds(panel->GetBounds()); |
| + new_bounds.set_origin(position); |
| + panel->SetPanelBounds(new_bounds); |
| + |
| + EnsureAvailableSpace(panel->GetBounds().width()); |
| + |
| + int x = panel->GetBounds().x(); |
| + Panels::iterator iter = panels_.begin(); |
| + for (; iter != panels_.end(); ++iter) { |
| + Panel* current_panel = *iter; |
|
jennb
2012/03/03 02:19:33
I was confusing current_panel with the panel you'r
jianli
2012/03/07 19:14:31
Dropped the temporary vars.
|
| + gfx::Rect current_bounds = current_panel->GetBounds(); |
| + if (x > current_bounds.x()) |
| + break; |
| } |
| + InsertPanelToCollection(panel, iter); |
| - dragging_panel_current_iterator_ = dragging_panel_original_iterator_ = |
| - panels_.end(); |
| + StartDraggingPanelLocally(panel); |
| + // This will automatically update all affected panels due to the insertion. |
| RefreshLayout(); |
| } |