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; |
+} |