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 63d8597d9d6f5f2636a81070322f1bde3a44449f..42daf8087f2e81d42002662a388b2c06364cadd9 100644 |
--- a/chrome/browser/ui/panels/docked_panel_strip.cc |
+++ b/chrome/browser/ui/panels/docked_panel_strip.cc |
@@ -11,6 +11,8 @@ |
#include "base/logging.h" |
#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,8 +62,7 @@ DockedPanelStrip::DockedPanelStrip(PanelManager* panel_manager) |
are_titlebars_up_(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() { |
@@ -87,6 +88,15 @@ void DockedPanelStrip::AddPanel(Panel* panel) { |
DCHECK_NE(this, panel->panel_strip()); |
panel->set_panel_strip(this); |
+ if (panel->initialized()) { |
jennb
2012/03/08 23:41:09
if (panel !initialized)
insert newly created
els
jianli
2012/03/09 21:48:58
Done.
|
+ if (panel->in_preview_mode()) |
+ InsertPreviewedPanel(panel); |
+ else |
+ InsertExistingPanel(panel); |
+ } else { |
+ InsertNewlyCreatedPanel(panel); |
+ } |
+ |
// Always update limits, even on existing panels, in case the limits changed |
// while panel was out of the strip. |
int max_panel_width = GetMaxPanelWidth(); |
@@ -94,80 +104,111 @@ void DockedPanelStrip::AddPanel(Panel* panel) { |
panel->SetSizeRange(gfx::Size(kPanelMinWidth, kPanelMinHeight), |
gfx::Size(max_panel_width, max_panel_height)); |
+ panel->SetAppIconVisibility(true); |
+ panel->SetAlwaysOnTop(true); |
+} |
+ |
+ |
jennb
2012/03/08 23:41:09
Extra blank line.
jianli
2012/03/09 21:48:58
Done.
|
+void DockedPanelStrip::InsertPreviewedPanel(Panel* panel) { |
+ DCHECK(panel->initialized() && panel->in_preview_mode()); |
+ |
+ FitPanelWithWidth(panel->GetBounds().width()); |
+ |
+ int x = panel->GetBounds().x(); |
+ Panels::iterator iter = panels_.begin(); |
+ for (; iter != panels_.end(); ++iter) |
+ if (x > (*iter)->GetBounds().x()) |
+ break; |
+ panels_.insert(iter, panel); |
+ |
+ // This will automatically update all affected panels due to the insertion. |
+ if (iter != panels_.end()) |
+ RefreshLayout(); |
+} |
+ |
+void DockedPanelStrip::InsertExistingPanel(Panel* panel) { |
+ DCHECK(panel->initialized() && !panel->in_preview_mode()); |
+ |
gfx::Size restored_size = panel->restored_size(); |
int height = restored_size.height(); |
int width = restored_size.width(); |
- if (panel->initialized()) { |
- int x = FitPanelWithWidth(width); |
+ int x = FitPanelWithWidth(width); |
- Panel::ExpansionState expansion_state_to_restore; |
- if (panel->expansion_state() == Panel::EXPANDED) { |
- expansion_state_to_restore = Panel::EXPANDED; |
+ Panel::ExpansionState expansion_state_to_restore; |
+ if (panel->expansion_state() == Panel::EXPANDED) { |
+ expansion_state_to_restore = Panel::EXPANDED; |
+ } else { |
+ if (are_titlebars_up_ || panel->IsDrawingAttention()) { |
+ expansion_state_to_restore = Panel::TITLE_ONLY; |
+ height = panel->TitleOnlyHeight(); |
} else { |
- if (are_titlebars_up_ || panel->IsDrawingAttention()) { |
- expansion_state_to_restore = Panel::TITLE_ONLY; |
- height = panel->TitleOnlyHeight(); |
- } else { |
- expansion_state_to_restore = Panel::MINIMIZED; |
- height = Panel::kMinimizedPanelHeight; |
- } |
- IncrementMinimizedPanels(); |
+ expansion_state_to_restore = Panel::MINIMIZED; |
+ height = Panel::kMinimizedPanelHeight; |
} |
- int y = |
- GetBottomPositionForExpansionState(expansion_state_to_restore) - height; |
- panel->SetPanelBounds(gfx::Rect(x, y, width, height)); |
+ IncrementMinimizedPanels(); |
+ } |
+ int y = |
+ GetBottomPositionForExpansionState(expansion_state_to_restore) - height; |
+ panel->SetPanelBounds(gfx::Rect(x, y, width, height)); |
- // Update the minimized state to reflect current titlebar mode. |
- // Do this AFTER setting panel bounds to avoid an extra bounds change. |
- if (panel->expansion_state() != Panel::EXPANDED) |
- panel->SetExpansionState(expansion_state_to_restore); |
+ // Update the minimized state to reflect current titlebar mode. |
+ // Do this AFTER setting panel bounds to avoid an extra bounds change. |
+ if (panel->expansion_state() != Panel::EXPANDED) |
+ panel->SetExpansionState(expansion_state_to_restore); |
- } else { |
- // Initialize the newly created panel. Does not bump any panels from strip. |
- if (height == 0 && width == 0 && panel_manager_->auto_sizing_enabled()) { |
- // Auto resizable is enabled only if no initial size is provided. |
- panel->SetAutoResizable(true); |
- } else { |
- if (height == 0) |
- height = width / kPanelDefaultWidthToHeightRatio; |
- if (width == 0) |
- width = height * kPanelDefaultWidthToHeightRatio; |
- } |
+ panels_.push_back(panel); |
+} |
- // Constrain sizes to limits. |
- if (width < kPanelMinWidth) |
- width = kPanelMinWidth; |
- else if (width > max_panel_width) |
- width = max_panel_width; |
- |
- if (height < kPanelMinHeight) |
- height = kPanelMinHeight; |
- else if (height > max_panel_height) |
- height = max_panel_height; |
- |
- panel->set_restored_size(gfx::Size(width, height)); |
- int x = GetRightMostAvailablePosition() - width; |
- int y = display_area_.bottom() - height; |
- |
- // Keep panel visible in the strip even if overlap would occur. |
- // Panel is moved to overflow from the strip after a delay. |
- if (x < display_area_.x()) { |
- x = display_area_.x(); |
- panel->set_has_temporary_layout(true); |
- MessageLoop::current()->PostDelayedTask( |
- FROM_HERE, |
- base::Bind(&DockedPanelStrip::DelayedMovePanelToOverflow, |
- base::Unretained(this), |
- panel), |
- base::TimeDelta::FromMilliseconds(PanelManager::AdjustTimeInterval( |
- kMoveNewPanelToOverflowDelayMs))); |
- } |
- panel->Initialize(gfx::Rect(x, y, width, height)); |
+void DockedPanelStrip::InsertNewlyCreatedPanel(Panel* panel) { |
+ DCHECK(!panel->initialized()); |
+ |
+ int max_panel_width = GetMaxPanelWidth(); |
+ int max_panel_height = GetMaxPanelHeight(); |
+ gfx::Size restored_size = panel->restored_size(); |
+ int height = restored_size.height(); |
+ int width = restored_size.width(); |
+ |
+ // Initialize the newly created panel. Does not bump any panels from strip. |
+ if (height == 0 && width == 0 && panel_manager_->auto_sizing_enabled()) { |
+ // Auto resizable is enabled only if no initial size is provided. |
+ panel->SetAutoResizable(true); |
+ } else { |
+ if (height == 0) |
+ height = width / kPanelDefaultWidthToHeightRatio; |
+ if (width == 0) |
+ width = height * kPanelDefaultWidthToHeightRatio; |
} |
- // Set panel properties for this strip. |
- panel->SetAppIconVisibility(true); |
+ // Constrain sizes to limits. |
+ if (width < kPanelMinWidth) |
+ width = kPanelMinWidth; |
+ else if (width > max_panel_width) |
+ width = max_panel_width; |
+ |
+ if (height < kPanelMinHeight) |
+ height = kPanelMinHeight; |
+ else if (height > max_panel_height) |
+ height = max_panel_height; |
+ |
+ panel->set_restored_size(gfx::Size(width, height)); |
+ int x = GetRightMostAvailablePosition() - width; |
+ int y = display_area_.bottom() - height; |
+ |
+ // Keep panel visible in the strip even if overlap would occur. |
+ // Panel is moved to overflow from the strip after a delay. |
+ if (x < display_area_.x()) { |
+ x = display_area_.x(); |
+ panel->set_has_temporary_layout(true); |
+ MessageLoop::current()->PostDelayedTask( |
+ FROM_HERE, |
+ base::Bind(&DockedPanelStrip::DelayedMovePanelToOverflow, |
+ base::Unretained(this), |
+ panel), |
+ base::TimeDelta::FromMilliseconds(PanelManager::AdjustTimeInterval( |
+ kMoveNewPanelToOverflowDelayMs))); |
+ } |
+ panel->Initialize(gfx::Rect(x, y, width, height)); |
if (panel->has_temporary_layout()) |
panels_in_temporary_layout_.insert(panel); |
@@ -208,16 +249,21 @@ void DockedPanelStrip::RemovePanel(Panel* panel) { |
// to it. We need to update the iterator in that case. |
DCHECK(dragging_panel_current_iterator_ == panels_.end() || |
*dragging_panel_current_iterator_ != panel); |
- bool update_iterator_after_erase = |
- (dragging_panel_original_iterator_ != panels_.end() && |
- *dragging_panel_original_iterator_ == panel); |
// Optimize for the common case of removing the last panel. |
DCHECK(!panels_.empty()); |
if (panels_.back() == panel) { |
panels_.pop_back(); |
- if (update_iterator_after_erase) |
- dragging_panel_original_iterator_ = panels_.end(); |
+ |
+ // Update the saved panel placement if needed. This is because we might remove |
+ // |saved_panel_placement_.left_panel_|. |
+ // Note: if |left_panel_| moves to overflow and then comes back, it is OK to |
+ // restore the panel to the end of list since we do not want to deal with |
+ // this case specially. |
+ if (saved_panel_placement_.panel && |
+ saved_panel_placement_.left_panel_ == panel) |
+ saved_panel_placement_.left_panel_ = NULL; |
+ |
// No need to refresh layout as the remaining panels are unaffected. |
// Just check if other panels can now fit in the freed up space. |
panel_manager_->MovePanelsOutOfOverflowIfCanFit(); |
@@ -225,8 +271,13 @@ void DockedPanelStrip::RemovePanel(Panel* panel) { |
Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); |
DCHECK(iter != panels_.end()); |
iter = panels_.erase(iter); |
- if (update_iterator_after_erase) |
- dragging_panel_original_iterator_ = iter; |
+ |
+ // Update the saved panel placement if needed. This is because we might remove |
+ // |saved_panel_placement_.left_panel_|. |
+ if (saved_panel_placement_.panel && |
+ saved_panel_placement_.left_panel_ == panel) |
+ saved_panel_placement_.left_panel_ = *iter; |
+ |
RefreshLayout(); |
} |
} |
@@ -236,24 +287,72 @@ 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_.left_panel_ = |
+ (iter == panels_.end()) ? NULL : *iter; |
+} |
+ |
+void DockedPanelStrip::RestorePanelToSavedPlacement() { |
+ DCHECK(saved_panel_placement_.panel); |
+ |
+ Panel* panel = saved_panel_placement_.panel; |
+ |
+ // 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. |
jennb
2012/03/08 23:41:09
nit: rephrase the if-comment to match the if-condi
jianli
2012/03/09 21:48:58
Done.
|
+ if (next_panel != saved_panel_placement_.left_panel_) { |
+ // Remove this panel from its current position. |
+ panels_.erase(iter); |
+ |
+ // Insert this panel into its previous position. |
+ if (saved_panel_placement_.left_panel_) { |
+ Panels::iterator iter_to_insert_before = std::find(panels_.begin(), |
+ panels_.end(), saved_panel_placement_.left_panel_); |
+ DCHECK(iter_to_insert_before != panels_.end()); |
+ panels_.insert(iter_to_insert_before, panel); |
+ } else { |
+ panels_.push_back(panel); |
+ } |
+ } |
+ |
+ RefreshLayout(); |
+ |
+ DiscardSavedPanelPlacement(); |
+} |
+ |
+void DockedPanelStrip::DiscardSavedPanelPlacement() { |
+ DCHECK(saved_panel_placement_.panel); |
+ saved_panel_placement_.panel = NULL; |
jennb
2012/03/08 23:41:09
Should clear out saved pointer to left_panel too.
jianli
2012/03/09 21:48:58
Done.
|
+} |
+ |
bool DockedPanelStrip::CanDragPanel(const Panel* panel) const { |
// Only the panels having temporary layout can't be dragged. |
return !panel->has_temporary_layout(); |
} |
-Panel* DockedPanelStrip::dragging_panel() const { |
- return dragging_panel_current_iterator_ == panels_.end() ? NULL : |
- *dragging_panel_current_iterator_; |
-} |
- |
-void DockedPanelStrip::StartDraggingPanel(Panel* panel) { |
+void DockedPanelStrip::StartDraggingPanelWithinStrip(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::DragPanelWithinStrip(Panel* panel, |
+ int delta_x, |
+ int delta_y) { |
if (!delta_x) |
return; |
@@ -326,39 +425,16 @@ 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::EndDraggingPanelWithinStrip(Panel* panel, bool aborted) { |
+ dragging_panel_current_iterator_ = panels_.end(); |
jennb
2012/03/08 23:41:09
Shame that you lose this iterator right before you
jianli
2012/03/09 21:48:58
Not sure I understand this comment. I want to sepa
|
- // 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_ = dragging_panel_original_iterator_ = |
- panels_.end(); |
- |
- RefreshLayout(); |
+ // Calls RefreshLayout to update the dragging panel to its final position |
+ // when the drag ends normally. Otherwise, the drag within this strip is |
+ // aborted because either the drag enters other strip or the drag is |
+ // cancelled. Either way, we don't need to do anything here and let the drag |
+ // controller handle the inter-strip transition or the drag cancellation. |
+ if (!aborted) |
+ RefreshLayout(); |
} |
void DockedPanelStrip::OnPanelExpansionStateChanged(Panel* panel) { |
@@ -524,7 +600,7 @@ bool DockedPanelStrip::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { |
// If the panel is showing titlebar only, we want to keep it up when it is |
// being dragged. |
- if (state == Panel::TITLE_ONLY && panel == dragging_panel()) |
+ if (state == Panel::TITLE_ONLY && panel->in_preview_mode()) |
jennb
2012/03/08 23:41:09
Keep old code here? It's obvious you want to leave
jianli
2012/03/09 21:48:58
Done.
|
return true; |
// We do not want to bring up other minimized panels if the mouse is over |
@@ -717,8 +793,8 @@ void DockedPanelStrip::RefreshLayout() { |
if (x < display_area_.x()) |
break; |
- // Don't update the docked panel that is currently dragged. |
- if (panel != dragging_panel()) { |
+ // Don't update the docked panel that is in preview mode. |
+ if (!panel->in_preview_mode()) { |
new_bounds.set_x(x); |
new_bounds.set_y( |
GetBottomPositionForExpansionState(panel->expansion_state()) - |
@@ -731,6 +807,8 @@ void DockedPanelStrip::RefreshLayout() { |
// Add/remove panels from/to overflow. A change in work area or the |
// resize/removal of a panel may affect how many panels fit in the strip. |
+ // TODO(jianli): Need to handle the case that panel in preview mode could be |
jennb
2012/03/08 23:41:09
crbug this and reference bug # here pls.
jianli
2012/03/09 21:48:58
Done.
|
+ // moved to overflow. |
if (panel_iter != panels_.end()) |
panel_manager_->MovePanelsToOverflow(*panel_iter); |
else |