Index: chrome/browser/views/extensions/extension_shelf.cc |
diff --git a/chrome/browser/views/extensions/extension_shelf.cc b/chrome/browser/views/extensions/extension_shelf.cc |
index 77df55aff7c191f3f9866125c164e1907e5cd072..3ba801c7d130e2f213a42dd491e07878214aa2a2 100644 |
--- a/chrome/browser/views/extensions/extension_shelf.cc |
+++ b/chrome/browser/views/extensions/extension_shelf.cc |
@@ -153,6 +153,10 @@ class ExtensionShelf::Toolstrip : public views::View, |
void DoHideShelfHandle(); |
void StopHandleTimer(); |
+ // Expand / Collapse |
+ void Expand(int height, const GURL& url); |
+ void Collapse(const GURL& url); |
+ |
// BrowserBubble::Delegate |
virtual void BubbleBrowserWindowMoved(BrowserBubble* bubble); |
virtual void BubbleBrowserWindowClosing(BrowserBubble* bubble); |
@@ -254,9 +258,8 @@ void ExtensionShelf::Toolstrip::Paint(gfx::Canvas* canvas) { |
gfx::Size ExtensionShelf::Toolstrip::GetPreferredSize() { |
gfx::Size sz = title_->GetPreferredSize(); |
sz.set_width(std::max(view()->width(), sz.width())); |
- if (!expanded_) { |
+ if (!expanded_) |
sz.Enlarge(2 + kHandlePadding * 2, kHandlePadding * 2); |
- } |
if (dragging_ || expanded_) { |
gfx::Size extension_size = view()->GetPreferredSize(); |
sz.Enlarge(0, extension_size.height() + 2); |
@@ -333,33 +336,17 @@ void ExtensionShelf::Toolstrip::OnMouseReleased(const views::MouseEvent& event, |
View::ConvertPointToView(NULL, shelf_, &loc); |
shelf_->DropExtension(this, loc, canceled); |
AttachToShelf(true); |
- } else if (!canceled && |
- info_.mole.is_valid() && info_.toolstrip.is_valid()) { |
+ } else if (!canceled) { |
// Toggle mole to either expanded or collapsed. |
- expanded_ = !expanded_; |
- view()->set_is_toolstrip(!expanded_); |
+ // TODO(erikkay) If there's no valid URL in the manifest, should we |
+ // post an event to the toolstrip in this case? |
if (expanded_) { |
- host_->NavigateToURL(info_.mole); |
- StopHandleTimer(); |
- DetachFromShelf(false); |
- |
- gfx::Size extension_size = view()->GetPreferredSize(); |
- extension_size.set_height(info_.mole_height); |
- view()->SetPreferredSize(extension_size); |
- LayoutHandle(); |
+ if (info_.toolstrip.is_valid()) |
+ shelf_->CollapseToolstrip(host_, info_.toolstrip); |
} else { |
- gfx::Size extension_size = view()->GetPreferredSize(); |
- extension_size.set_height(kToolstripHeight); |
- view()->SetPreferredSize(extension_size); |
- |
- host_->NavigateToURL(info_.toolstrip); |
- AttachToShelf(false); |
+ if (info_.mole.is_valid()) |
+ shelf_->ExpandToolstrip(host_, info_.mole, info_.mole_height); |
} |
- |
- // This is to prevent flickering as the page loads and lays out. |
- // Once the navigation is finished, ExtensionView will wind up setting |
- // visibility to true. |
- view()->SetVisible(false); |
} |
} |
@@ -414,6 +401,7 @@ void ExtensionShelf::Toolstrip::BubbleBrowserWindowClosing( |
} |
void ExtensionShelf::Toolstrip::DetachFromShelf(bool browserDetach) { |
+ DCHECK(handle_.get()); |
DCHECK(!placeholder_view_); |
if (browserDetach && handle_->attached()) |
handle_->DetachFromBrowser(); |
@@ -430,6 +418,8 @@ void ExtensionShelf::Toolstrip::DetachFromShelf(bool browserDetach) { |
} |
void ExtensionShelf::Toolstrip::AttachToShelf(bool browserAttach) { |
+ DCHECK(handle_.get()); |
+ DCHECK(placeholder_view_); |
if (browserAttach && !handle_->attached()) |
handle_->AttachToBrowser(); |
@@ -473,6 +463,56 @@ void ExtensionShelf::Toolstrip::StopHandleTimer() { |
timer_factory_.RevokeAll(); |
} |
+void ExtensionShelf::Toolstrip::Expand(int height, const GURL& url) { |
+ DCHECK(!expanded_); |
+ |
+ DoShowShelfHandle(); |
+ |
+ expanded_ = true; |
+ view()->set_is_toolstrip(!expanded_); |
+ |
+ bool navigate = (!url.is_empty() && url != host_->GetURL()); |
+ if (navigate) |
+ host_->NavigateToURL(url); |
+ |
+ StopHandleTimer(); |
+ DetachFromShelf(false); |
+ |
+ gfx::Size extension_size = view()->GetPreferredSize(); |
+ extension_size.set_height(height); |
+ view()->SetPreferredSize(extension_size); |
+ LayoutHandle(); |
+ |
+ // This is to prevent flickering as the page loads and lays out. |
+ // Once the navigation is finished, ExtensionView will wind up setting |
+ // visibility to true. |
+ if (navigate) |
+ view()->SetVisible(false); |
+} |
+ |
+void ExtensionShelf::Toolstrip::Collapse(const GURL& url) { |
+ DCHECK(expanded_); |
+ expanded_ = false; |
+ view()->set_is_toolstrip(!expanded_); |
+ |
+ gfx::Size extension_size = view()->GetPreferredSize(); |
+ extension_size.set_height(kToolstripHeight); |
+ view()->SetPreferredSize(extension_size); |
+ AttachToShelf(false); |
+ |
+ if (!url.is_empty() && url != host_->GetURL()) { |
+ host_->NavigateToURL(url); |
+ |
+ // This is to prevent flickering as the page loads and lays out. |
+ // Once the navigation is finished, ExtensionView will wind up setting |
+ // visibility to true. |
+ view()->SetVisible(false); |
+ } |
+ |
+ // Must use the delay due to bug 18248. |
+ HideShelfHandle(kHideDelayMs); |
+} |
+ |
void ExtensionShelf::Toolstrip::ShowShelfHandle() { |
StopHandleTimer(); |
if (handle_visible()) |
@@ -500,19 +540,21 @@ void ExtensionShelf::Toolstrip::HideShelfHandle(int delay_ms) { |
//////////////////////////////////////////////////////////////////////////////// |
ExtensionShelf::ExtensionShelf(Browser* browser) |
- : model_(new ExtensionShelfModel(browser)) { |
+ : model_(browser->extension_shelf_model()) { |
model_->AddObserver(this); |
LoadFromModel(); |
EnableCanvasFlippingForRTLUI(true); |
} |
ExtensionShelf::~ExtensionShelf() { |
- int count = model_->count(); |
- for (int i = 0; i < count; ++i) { |
- delete ToolstripAtIndex(i); |
- model_->SetToolstripDataAt(i, NULL); |
+ if (model_) { |
+ int count = model_->count(); |
+ for (int i = 0; i < count; ++i) { |
+ delete ToolstripAtIndex(i); |
+ model_->SetToolstripDataAt(i, NULL); |
+ } |
+ model_->RemoveObserver(this); |
} |
- model_->RemoveObserver(this); |
} |
void ExtensionShelf::Paint(gfx::Canvas* canvas) { |
@@ -563,6 +605,8 @@ void ExtensionShelf::ChildPreferredSizeChanged(View* child) { |
void ExtensionShelf::Layout() { |
if (!GetParent()) |
return; |
+ if (!model_) |
+ return; |
int x = kLeftMargin; |
int y = kTopMargin; |
@@ -619,7 +663,7 @@ void ExtensionShelf::SetAccessibleName(const std::wstring& name) { |
void ExtensionShelf::ToolstripInsertedAt(ExtensionHost* host, |
int index) { |
model_->SetToolstripDataAt(index, |
- new Toolstrip(this, host, model_->ToolstripInfoAt(index))); |
+ new Toolstrip(this, host, model_->ToolstripAt(index).info)); |
bool had_views = GetChildViewCount() > 0; |
ExtensionView* view = host->view(); |
@@ -653,7 +697,15 @@ void ExtensionShelf::ToolstripMoved(ExtensionHost* host, int from_index, |
Layout(); |
} |
-void ExtensionShelf::ToolstripChangedAt(ExtensionHost* toolstrip, int index) { |
+void ExtensionShelf::ToolstripChanged(ExtensionShelfModel::iterator toolstrip) { |
+ Toolstrip* t = static_cast<Toolstrip*>(toolstrip->data); |
+ if (toolstrip->height > 0) { |
+ if (!t->expanded()) { |
+ t->Expand(toolstrip->height, toolstrip->url); |
+ } |
+ } else if (t->expanded()) { |
+ t->Collapse(toolstrip->url); |
+ } |
} |
void ExtensionShelf::ExtensionShelfEmpty() { |
@@ -666,6 +718,16 @@ void ExtensionShelf::ShelfModelReloaded() { |
LoadFromModel(); |
} |
+void ExtensionShelf::ShelfModelDeleting() { |
+ int count = model_->count(); |
+ for (int i = 0; i < count; ++i) { |
+ delete ToolstripAtIndex(i); |
+ model_->SetToolstripDataAt(i, NULL); |
+ } |
+ model_->RemoveObserver(this); |
+ model_ = NULL; |
+} |
+ |
void ExtensionShelf::OnExtensionMouseEvent(ExtensionView* view) { |
Toolstrip *toolstrip = ToolstripForView(view); |
if (toolstrip) |
@@ -689,12 +751,23 @@ void ExtensionShelf::DropExtension(Toolstrip* toolstrip, const gfx::Point& pt, |
} |
if (toolstrip == dest_toolstrip) |
return; |
- int from = model_->IndexOfToolstrip(toolstrip->host()); |
- int to = model_->IndexOfToolstrip(dest_toolstrip->host()); |
+ int from = model_->IndexOfHost(toolstrip->host()); |
+ int to = model_->IndexOfHost(dest_toolstrip->host()); |
DCHECK(from != to); |
model_->MoveToolstripAt(from, to); |
} |
+void ExtensionShelf::ExpandToolstrip(ExtensionHost* host, const GURL& url, |
+ int height) { |
+ ExtensionShelfModel::iterator toolstrip = model_->ToolstripForHost(host); |
+ model_->ExpandToolstrip(toolstrip, url, height); |
+} |
+ |
+void ExtensionShelf::CollapseToolstrip(ExtensionHost* host, const GURL& url) { |
+ ExtensionShelfModel::iterator toolstrip = model_->ToolstripForHost(host); |
+ model_->CollapseToolstrip(toolstrip, url); |
+} |
+ |
void ExtensionShelf::InitBackground(gfx::Canvas* canvas, const SkRect& subset) { |
if (!background_.empty()) |
return; |
@@ -749,7 +822,7 @@ ExtensionShelf::Toolstrip* ExtensionShelf::ToolstripAtX(int x) { |
} |
ExtensionShelf::Toolstrip* ExtensionShelf::ToolstripAtIndex(int index) { |
- return static_cast<Toolstrip*>(model_->ToolstripDataAt(index)); |
+ return static_cast<Toolstrip*>(model_->ToolstripAt(index).data); |
} |
ExtensionShelf::Toolstrip* ExtensionShelf::ToolstripForView( |
@@ -760,12 +833,11 @@ ExtensionShelf::Toolstrip* ExtensionShelf::ToolstripForView( |
if (view == toolstrip->view()) |
return toolstrip; |
} |
- NOTREACHED(); |
return NULL; |
} |
void ExtensionShelf::LoadFromModel() { |
int count = model_->count(); |
for (int i = 0; i < count; ++i) |
- ToolstripInsertedAt(model_->ToolstripAt(i), i); |
+ ToolstripInsertedAt(model_->ToolstripAt(i).host, i); |
} |