diff options
author | erikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-06 16:58:56 +0000 |
---|---|---|
committer | erikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-06 16:58:56 +0000 |
commit | 653c9eadfec2cde8d489556f93437212e382d2f1 (patch) | |
tree | 348e52e78b1399e62e4e81e2a7d7ec8da50b8d80 | |
parent | 74bad4b4c067b980ceb9d5b80c82ef67cc55826d (diff) | |
download | chromium_src-653c9eadfec2cde8d489556f93437212e382d2f1.zip chromium_src-653c9eadfec2cde8d489556f93437212e382d2f1.tar.gz chromium_src-653c9eadfec2cde8d489556f93437212e382d2f1.tar.bz2 |
Create a separate UI surface for extensions (bottom shelf) and remove them from the bookmarks bar (for now).
The current implementation doesn't do anything new except for always appear when extensions are loaded.
TEST=install an extension and see it show up in the new bottom bar
TEST=unit_tests.exe --gtest_filter=ExtensionViewTest.BottomBar
Review URL: http://codereview.chromium.org/112001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15417 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/browser.cc | 6 | ||||
-rw-r--r-- | chrome/browser/browser.h | 3 | ||||
-rw-r--r-- | chrome/browser/browser.vcproj | 8 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_shelf.cc | 205 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_shelf.h | 46 | ||||
-rwxr-xr-x | chrome/browser/extensions/extension_view.cc | 15 | ||||
-rwxr-xr-x | chrome/browser/extensions/extension_view_unittest.cc | 30 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.cc | 10 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.cc | 158 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.h | 12 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.cc | 31 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.h | 10 |
12 files changed, 341 insertions, 193 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 45c6108..78f1293 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -870,8 +870,10 @@ void Browser::ShowFindBar() { bool Browser::SupportsWindowFeature(WindowFeature feature) const { unsigned int features = FEATURE_INFOBAR | FEATURE_DOWNLOADSHELF; - if (type() == TYPE_NORMAL) - features |= FEATURE_BOOKMARKBAR; + if (type() == TYPE_NORMAL) { + features |= FEATURE_BOOKMARKBAR; + features |= FEATURE_EXTENSIONSHELF; + } if (!window_ || !window_->IsFullscreen()) { if (type() == TYPE_NORMAL) features |= FEATURE_TABSTRIP | FEATURE_TOOLBAR; diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index 2a5db13..580cf37 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -60,7 +60,8 @@ class Browser : public TabStripModelDelegate, FEATURE_LOCATIONBAR = 8, FEATURE_BOOKMARKBAR = 16, FEATURE_INFOBAR = 32, - FEATURE_DOWNLOADSHELF = 64 + FEATURE_DOWNLOADSHELF = 64, + FEATURE_EXTENSIONSHELF = 128 }; // Maximized state on creation. diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj index 4685780..e8cc6c2 100644 --- a/chrome/browser/browser.vcproj +++ b/chrome/browser/browser.vcproj @@ -1990,6 +1990,14 @@ > </File> <File + RelativePath=".\extensions\extension_shelf.cc" + > + </File> + <File + RelativePath=".\extensions\extension_shelf.h" + > + </File> + <File RelativePath=".\extensions\extension_tabs_module.cc" > </File> diff --git a/chrome/browser/extensions/extension_shelf.cc b/chrome/browser/extensions/extension_shelf.cc new file mode 100644 index 0000000..07cfdf4 --- /dev/null +++ b/chrome/browser/extensions/extension_shelf.cc @@ -0,0 +1,205 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/extension_shelf.h" + +#include "base/logging.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/extensions/extension.h" +#include "chrome/browser/extensions/extension_view.h" +#include "chrome/browser/extensions/extensions_service.h" +#include "chrome/browser/profile.h" +#include "chrome/common/notification_service.h" +#include "skia/ext/skia_utils.h" + +namespace { + +// Margins around the content. +static const int kTopMargin = 1; +static const int kBottomMargin = 2; +static const int kLeftMargin = 1; +static const int kRightMargin = 1; + +// Padding between extension toolstrips. +static const int kToolstripPadding = 2; + +// Preferred height of the ExtensionShelf. +static const int kShelfHeight = 29; + +// Colors for the ExtensionShelf. +static const SkColor kBackgroundColor = SkColorSetRGB(230, 237, 244); +static const SkColor kBorderColor = SkColorSetRGB(201, 212, 225); +static const SkColor kSeparatorHighlightColor = SkColorSetRGB(247, 250, 253); + +// TODO(erikkay) convert back to a gradient when Glen figures out the +// specs. +// static const SkColor kBackgroundColor = SkColorSetRGB(237, 244, 252); +// static const SkColor kTopGradientColor = SkColorSetRGB(222, 234, 248); + +} // namespace + + +ExtensionShelf::ExtensionShelf(Browser* browser) : browser_(browser) { + // Watch extensions loaded notification. + NotificationService* ns = NotificationService::current(); + Source<Profile> ns_source(browser->profile()->GetOriginalProfile()); + ns->AddObserver(this, NotificationType::EXTENSIONS_LOADED, + NotificationService::AllSources()); + + // Add any already-loaded extensions now, since we missed the notification for + // those. + ExtensionsService* service = browser_->profile()->GetExtensionsService(); + if (service) { // This can be null in unit tests. + if (AddExtensionViews(service->extensions())) { + Layout(); + SchedulePaint(); + } + } +} + +ExtensionShelf::~ExtensionShelf() { + NotificationService* ns = NotificationService::current(); + ns->RemoveObserver(this, NotificationType::EXTENSIONS_LOADED, + NotificationService::AllSources()); +} + +void ExtensionShelf::Paint(ChromeCanvas* canvas) { +#if 0 + // TODO(erikkay) re-enable this when Glen has the gradient values worked out. + SkPaint paint; + paint.setShader(skia::CreateGradientShader(0, + height(), + kTopGradientColor, + kBackgroundColor))->safeUnref(); + canvas->FillRectInt(0, 0, width(), height(), paint); +#else + canvas->FillRectInt(kBackgroundColor, 0, 0, width(), height()); +#endif + + canvas->FillRectInt(kBorderColor, 0, 0, width(), 1); + canvas->FillRectInt(kBorderColor, 0, height() - 1, width(), 1); + + int count = GetChildViewCount(); + for (int i = 0; i < count; ++i) { + int right = GetChildViewAt(i)->bounds().right(); + int h = height() - 2; + canvas->FillRectInt(kBorderColor, right, 1, 1, h); + canvas->FillRectInt(kSeparatorHighlightColor, right + 1, 1, 1, h); + } + + SkRect background_rect = { + SkIntToScalar(0), + SkIntToScalar(1), + SkIntToScalar(1), + SkIntToScalar(height() - 2)}; + InitBackground(canvas, background_rect); +} + +gfx::Size ExtensionShelf::GetPreferredSize() { + if (HasExtensionViews()) + return gfx::Size(0, kShelfHeight); + return gfx::Size(0, 0); +} + +void ExtensionShelf::Layout() { + if (!GetParent()) + return; + + int x = kLeftMargin; + int y = kTopMargin; + int content_height = height() - kTopMargin - kBottomMargin; + int max_x = width() - kRightMargin; + + int count = GetChildViewCount(); + for (int i = 0; i < count; ++i) { + views::View* child = GetChildViewAt(i); + gfx::Size pref = child->GetPreferredSize(); + int next_x = x + pref.width() + kToolstripPadding; + child->SetVisible(next_x < max_x); + child->SetBounds(x, y, pref.width(), content_height); + child->Layout(); + x = next_x; + } +} + +void ExtensionShelf::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + switch (type.value) { + case NotificationType::EXTENSIONS_LOADED: { + const ExtensionList* extensions = Details<ExtensionList>(details).ptr(); + if (AddExtensionViews(extensions)) { + Layout(); + SchedulePaint(); + // TODO(erikkay) come up with a better way to notify parents + if (GetParent()) + GetParent()->Layout(); + } + break; + } + default: + DCHECK(false) << "Unhandled notification of type: " << type.value; + break; + } +} + +bool ExtensionShelf::AddExtensionViews(const ExtensionList* extensions) { + bool added_toolstrip = false; + ExtensionsService* service = browser_->profile()->GetExtensionsService(); + for (ExtensionList::const_iterator extension = extensions->begin(); + extension != extensions->end(); ++extension) { + for (std::vector<std::string>::const_iterator toolstrip_path = + (*extension)->toolstrips().begin(); + toolstrip_path != (*extension)->toolstrips().end(); ++toolstrip_path) { + ExtensionView* toolstrip = + service->CreateView(*extension, + (*extension)->GetResourceURL(*toolstrip_path), + browser_); + if (!background_.empty()) + toolstrip->SetBackground(background_); + AddChildView(toolstrip); + added_toolstrip = true; + } + } + return added_toolstrip; +} + +bool ExtensionShelf::HasExtensionViews() { + return GetChildViewCount() > 0; +} + +void ExtensionShelf::InitBackground(ChromeCanvas* canvas, + const SkRect& subset) { + if (!background_.empty()) + return; + + const SkBitmap& background = canvas->getDevice()->accessBitmap(false); + + // Extract the correct subset of the toolstrip background into a bitmap. We + // must use a temporary here because extractSubset() returns a bitmap that + // references pixels in the original one and we want to actually make a copy + // that will have a long lifetime. + SkBitmap temp; + temp.setConfig(background.config(), + static_cast<int>(subset.width()), + static_cast<int>(subset.height())); + + SkRect mapped_subset = subset; + bool result = canvas->getTotalMatrix().mapRect(&mapped_subset); + DCHECK(result); + + SkIRect isubset; + mapped_subset.round(&isubset); + result = background.extractSubset(&temp, isubset); + if (!result) + return; + + temp.copyTo(&background_, temp.config()); + DCHECK(background_.readyToDraw()); + + // Tell all extension views about the new background + int count = GetChildViewCount(); + for (int i = 0; i < count; ++i) + static_cast<ExtensionView*>(GetChildViewAt(i))->SetBackground(background_); +} diff --git a/chrome/browser/extensions/extension_shelf.h b/chrome/browser/extensions/extension_shelf.h new file mode 100644 index 0000000..cd7340f --- /dev/null +++ b/chrome/browser/extensions/extension_shelf.h @@ -0,0 +1,46 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_SHELF_H_ +#define CHROME_BROWSER_EXTENSIONS_EXTENSION_SHELF_H_ + +#include "chrome/browser/extensions/extensions_service.h" +#include "app/gfx/chrome_canvas.h" +#include "chrome/common/notification_observer.h" +#include "chrome/views/view.h" + +class Browser; + +class ExtensionShelf : public views::View, + public NotificationObserver { + public: + explicit ExtensionShelf(Browser* browser); + virtual ~ExtensionShelf(); + + // View + virtual void Paint(ChromeCanvas* canvas); + virtual gfx::Size GetPreferredSize(); + virtual void Layout(); + + // NotificationService method. + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + bool AddExtensionViews(const ExtensionList* extensions); + bool HasExtensionViews(); + + private: + // Inits the background bitmap. + void InitBackground(ChromeCanvas* canvas, const SkRect& subset); + + Browser* browser_; + + // Background bitmap to draw under extension views. + SkBitmap background_; + + DISALLOW_COPY_AND_ASSIGN(ExtensionShelf); +}; + +#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_SHELF_H_ diff --git a/chrome/browser/extensions/extension_view.cc b/chrome/browser/extensions/extension_view.cc index 3f602d0..8070bf3 100755 --- a/chrome/browser/extensions/extension_view.cc +++ b/chrome/browser/extensions/extension_view.cc @@ -45,6 +45,9 @@ void ExtensionView::DidChangeBounds(const gfx::Rect& previous, // We can't send size zero because RenderWidget DCHECKs that. if (render_view_host()->view() && !current.IsEmpty()) render_view_host()->view()->SetSize(gfx::Size(width(), height())); + // Layout is where the HWND is properly positioned. + // TODO(erikkay) - perhaps this should be in HWNDView + Layout(); } void ExtensionView::ShowIfCompletelyLoaded() { @@ -75,13 +78,11 @@ void ExtensionView::DidContentsPreferredWidthChange(const int pref_width) { set_preferred_size(gfx::Size(pref_width, height())); SizeToPreferredSize(); - // TODO(rafaelw): This assumes that the extension view is a child of an - // ExtensionToolstrip, which is a child of the BookmarkBarView. There should - // be a way to do this where the ExtensionView doesn't have to know it's - // containment hierarchy. - if (GetParent() != NULL && GetParent()->GetParent() != NULL) { - GetParent()->GetParent()->Layout(); - GetParent()->GetParent()->SchedulePaint(); + // TODO(erikkay) There should be a way to do this where the ExtensionView + // doesn't have to know it's containment hierarchy. + if (GetParent() != NULL) { + GetParent()->Layout(); + GetParent()->SchedulePaint(); } } } diff --git a/chrome/browser/extensions/extension_view_unittest.cc b/chrome/browser/extensions/extension_view_unittest.cc index 3529022..ca1643a 100755 --- a/chrome/browser/extensions/extension_view_unittest.cc +++ b/chrome/browser/extensions/extension_view_unittest.cc @@ -5,6 +5,7 @@ #include "base/ref_counted.h" #include "chrome/browser/browser.h" #include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/extensions/extension_shelf.h" #include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/extension_host.h" #include "chrome/browser/extensions/extensions_service.h" @@ -105,3 +106,32 @@ IN_PROC_BROWSER_TEST_F(ExtensionViewTest, Index) { browser()->profile()->GetExtensionsService()->GetSiteInstanceForURL(url)); EXPECT_TRUE(host.got_message()); } + +// Tests that the ExtensionShelf initializes properly, notices that +// an extension loaded and has a view available, and then sets that up +// properly. +IN_PROC_BROWSER_TEST_F(ExtensionViewTest, BottomBar) { + // When initialized, there are no extension views and the preferred height + // should be zero. + scoped_ptr<ExtensionShelf> shelf(new ExtensionShelf(browser())); + ASSERT_FALSE(shelf->HasExtensionViews()); + ASSERT_EQ(shelf->GetPreferredSize().height(), 0); + + // Get the path to our extension. + FilePath path; + ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path)); + path = path.AppendASCII("extensions"). + AppendASCII("good").AppendASCII("extension1").AppendASCII("1"); + ASSERT_TRUE(file_util::DirectoryExists(path)); // sanity check + + // Wait for the extension to load and grab a pointer to it. + TestExtensionLoader loader(browser()->profile()); + Extension* extension = loader.Load(kExtensionId, path); + ASSERT_TRUE(extension); + GURL url = Extension::GetResourceURL(extension->url(), "toolstrip1.html"); + + // There should now be two extension views and preferred height of the view + // should be non-zero. + ASSERT_TRUE(shelf->HasExtensionViews()); + ASSERT_NE(shelf->GetPreferredSize().height(), 0); +} diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index 0026d18..0af48343 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -197,16 +197,6 @@ void ExtensionsService::OnExtensionInstalled(Extension* extension, NotificationType::EXTENSION_INSTALLED, NotificationService::AllSources(), Details<Extension>(extension)); - - // We open the NTP if the extension has a toolstrip and the bookmark bar is - // detached. We noticed that people got confused if something didn't obviously - // happen when installing an extension. - Browser* browser = BrowserList::GetLastActive(); - if (browser && browser->window() && - !browser->window()->IsBookmarkBarVisible() && - !extension->toolstrips().empty()) - browser->AddTabWithURL(GURL(chrome::kChromeUINewTabURL), GURL(), - PageTransition::LINK, true, -1, false, NULL); } Extension* ExtensionsService::GetExtensionByID(std::string id) { diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index 82e532b..df3e0c4 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -294,34 +294,6 @@ class BookmarkFolderButton : public views::MenuButton { DISALLOW_COPY_AND_ASSIGN(BookmarkFolderButton); }; -// ExtensionToolstrip ------------------------------------------------------- - -// A simple container with a border for an ExtensionView. -class ExtensionToolstrip : public views::View { - public: - ExtensionToolstrip(Extension* extension, const GURL& url, Browser* browser) - : view_(browser->profile()->GetExtensionsService()->CreateView( - extension, url, browser)) { - AddChildView(view_); - } - - ExtensionView* view() { return view_; } - - virtual gfx::Size GetPreferredSize() { - return view_->GetPreferredSize(); - } - - virtual void DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current) { - view_->SetBounds(GetLocalBounds(false)); - } - - private: - ExtensionView* view_; - - DISALLOW_COPY_AND_ASSIGN(ExtensionToolstrip); -}; - // DropInfo ------------------------------------------------------------------- // Tracks drops on the BookmarkBarView. @@ -429,8 +401,7 @@ BookmarkBarView::BookmarkBarView(Profile* profile, Browser* browser) overflow_button_(NULL), instructions_(NULL), bookmarks_separator_view_(NULL), - throbbing_view_(NULL), - num_extension_toolstrips_(0) { + throbbing_view_(NULL) { SetID(VIEW_ID_BOOKMARK_BAR); Init(); SetProfile(profile); @@ -460,14 +431,6 @@ void BookmarkBarView::SetProfile(Profile* profile) { // Cancels the current cancelable. NotifyModelChanged(); - // Remove the current buttons and extension toolstrips. - for (int i = GetBookmarkButtonCount() + num_extension_toolstrips_ - 1; - i >= 0; --i) { - View* child = GetChildViewAt(i); - RemoveChildView(child); - delete child; - } - profile_ = profile; if (model_) @@ -483,18 +446,6 @@ void BookmarkBarView::SetProfile(Profile* profile) { ns->AddObserver(this, NotificationType::BOOKMARK_BUBBLE_HIDDEN, ns_source); ns->AddObserver(this, NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, NotificationService::AllSources()); - ns->AddObserver(this, NotificationType::EXTENSIONS_LOADED, - NotificationService::AllSources()); - - // Add any already-loaded extensions now, since we missed the notification for - // those. - if (profile_->GetExtensionsService()) { // null in unit tests - if (AddExtensionToolstrips( - profile_->GetExtensionsService()->extensions())) { - Layout(); - SchedulePaint(); - } - } model_ = profile_->GetBookmarkModel(); model_->AddObserver(this); @@ -564,20 +515,6 @@ void BookmarkBarView::Layout() { overflow_pref.width() - kButtonPadding - bookmarks_separator_pref.width(); - // First, layout extension toolstrips. - // We put these always on the left as a temporary hack until we have the - // extension bar. Otherwise, people install extensions and they don't see - // anything happen and are confused. - for (int i = GetBookmarkButtonCount(); - i < GetBookmarkButtonCount() + num_extension_toolstrips_; ++i) { - views::View* child = GetChildViewAt(i); - gfx::Size pref = child->GetPreferredSize(); - int next_x = x + pref.width() + kButtonPadding; - child->SetVisible(next_x < max_x); - child->SetBounds(x, y, pref.width(), height); - x = next_x; - } - // Next, layout out the buttons. Any buttons that are placed beyond the // visible region and made invisible. if (GetBookmarkButtonCount() == 0 && model_ && model_->IsLoaded()) { @@ -694,13 +631,6 @@ void BookmarkBarView::Paint(ChromeCanvas* canvas) { canvas->drawRoundRect(rect, SkDoubleToScalar(roundness), SkDoubleToScalar(roundness), border_paint); - - SkRect toolstrip_background_rect = { - rect.fLeft + 1 + kNewtabBarRoundness, - rect.fTop + 1, - rect.fLeft + 1 + kNewtabBarRoundness + 1, - rect.fBottom - 1}; - InitToolstripBackground(canvas, toolstrip_background_rect); } else { SkPaint paint; paint.setShader(skia::CreateGradientShader(0, @@ -711,51 +641,6 @@ void BookmarkBarView::Paint(ChromeCanvas* canvas) { canvas->FillRectInt(kTopBorderColor, 0, 0, width(), 1); canvas->FillRectInt(kBottomBorderColor, 0, height() - 1, width(), 1); - - SkRect toolstrip_background_rect = { - SkIntToScalar(0), - SkIntToScalar(1), - SkIntToScalar(1), - SkIntToScalar(height() - 2)}; - InitToolstripBackground(canvas, toolstrip_background_rect); - } -} - -void BookmarkBarView::InitToolstripBackground(ChromeCanvas* canvas, - const SkRect& subset) { - if (!toolstrip_background_.empty()) - return; - - const SkBitmap& bookmarkbar_background = - canvas->getDevice()->accessBitmap(false); - - // Extract the correct subset of the toolstrip background into a bitmap. We - // must use a temporary here because extractSubset() returns a bitmap that - // references pixels in the original one and we want to actually make a copy - // that will have a long lifetime. - SkBitmap temp; - temp.setConfig(bookmarkbar_background.config(), - static_cast<int>(subset.width()), - static_cast<int>(subset.height())); - - SkRect mapped_subset = subset; - bool result = canvas->getTotalMatrix().mapRect(&mapped_subset); - DCHECK(result); - - SkIRect isubset; - mapped_subset.round(&isubset); - result = bookmarkbar_background.extractSubset(&temp, isubset); - if (!result) - return; - - temp.copyTo(&toolstrip_background_, temp.config()); - DCHECK(toolstrip_background_.readyToDraw()); - - // Tell all current toolstrips about the new background - for (int i = GetBookmarkButtonCount(); - i < GetBookmarkButtonCount() + num_extension_toolstrips_; ++i) { - static_cast<ExtensionToolstrip*>(GetChildViewAt(i))->view()->SetBackground( - toolstrip_background_); } } @@ -956,17 +841,12 @@ int BookmarkBarView::GetToolbarOverlap(bool return_max) { void BookmarkBarView::AnimationProgressed(const Animation* animation) { if (browser_) browser_->ToolbarSizeChanged(true); - - // Clear the toolstrip background so that we recreate it next time around the - // paint loop. - toolstrip_background_.reset(); } void BookmarkBarView::AnimationEnded(const Animation* animation) { if (browser_) browser_->ToolbarSizeChanged(false); - toolstrip_background_.reset(); SchedulePaint(); } @@ -1052,8 +932,8 @@ MenuButton* BookmarkBarView::CreateOverflowButton() { int BookmarkBarView::GetBookmarkButtonCount() { // We contain at least four non-bookmark button views: recently bookmarked, // bookmarks separator, chevrons (for overflow), the instruction - // label, as well as any ExtensionViews displaying toolstrips. - return GetChildViewCount() - 4 - num_extension_toolstrips_; + // label. + return GetChildViewCount() - 4; } void BookmarkBarView::Loaded(BookmarkModel* model) { @@ -1419,41 +1299,9 @@ void BookmarkBarView::Observe(NotificationType type, StopThrobbing(false); bubble_url_ = GURL(); break; - - case NotificationType::EXTENSIONS_LOADED: { - const ExtensionList* extensions = Details<ExtensionList>(details).ptr(); - if (AddExtensionToolstrips(extensions)) { - Layout(); - SchedulePaint(); - } - break; - } } } -bool BookmarkBarView::AddExtensionToolstrips(const ExtensionList* extensions) { - bool added_toolstrip = false; - for (ExtensionList::const_iterator extension = extensions->begin(); - extension != extensions->end(); ++extension) { - for (std::vector<std::string>::const_iterator toolstrip_path = - (*extension)->toolstrips().begin(); - toolstrip_path != (*extension)->toolstrips().end(); ++toolstrip_path) { - ExtensionToolstrip* toolstrip = - new ExtensionToolstrip(*extension, - (*extension)->GetResourceURL(*toolstrip_path), - browser_); - int index = GetBookmarkButtonCount() + num_extension_toolstrips_; - if (!toolstrip_background_.empty()) - toolstrip->view()->SetBackground(toolstrip_background_); - AddChildView(index, toolstrip); - added_toolstrip = true; - ++num_extension_toolstrips_; - } - } - - return added_toolstrip; -} - void BookmarkBarView::RemoveNotificationObservers() { NotificationService* ns = NotificationService::current(); Source<Profile> ns_source(profile_->GetOriginalProfile()); diff --git a/chrome/browser/views/bookmark_bar_view.h b/chrome/browser/views/bookmark_bar_view.h index 53d5e68..a5d1a4b 100644 --- a/chrome/browser/views/bookmark_bar_view.h +++ b/chrome/browser/views/bookmark_bar_view.h @@ -373,15 +373,6 @@ class BookmarkBarView : public views::View, // throbs. void StopThrobbing(bool immediate); - // Add any extension toolstrips which may be requested by the given - // extensions. Views for the toolstrips are inserted after the last bookmark - // button. Returns true if there were any new toolstrips added. - bool AddExtensionToolstrips(const ExtensionList* extensions); - - // Initializes the bitmap we use for the background of extension toolstrips by - // copying a subset of the current toolstrip background. - void InitToolstripBackground(ChromeCanvas* canvas, const SkRect& subset); - Profile* profile_; // Used for opening urls. @@ -434,9 +425,6 @@ class BookmarkBarView : public views::View, // overflow_button_ or a button on the bar. views::CustomButton* throbbing_view_; - // How many extension toolstrips we have showing in the toolbar. - int num_extension_toolstrips_; - // Background for extension toolstrips. SkBitmap toolstrip_background_; diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index fad5dd1..4d861f0 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -19,6 +19,7 @@ #include "chrome/browser/browser_list.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/encoding_menu_controller_delegate.h" +#include "chrome/browser/extensions/extension_shelf.h" #include "chrome/browser/find_bar_controller.h" #include "chrome/browser/view_ids.h" #include "chrome/browser/views/about_chrome_view.h" @@ -284,7 +285,8 @@ BrowserView::BrowserView(Browser* browser) initialized_(false), ignore_layout_(false), hung_window_detector_(&hung_plugin_action_), - ticker_(0) { + ticker_(0), + extension_shelf_(NULL) { InitClass(); browser_->tabstrip_model()->AddObserver(this); } @@ -1214,7 +1216,8 @@ void BrowserView::Layout() { int top = LayoutTabStrip(); top = LayoutToolbar(top); top = LayoutBookmarkAndInfoBars(top); - int bottom = LayoutDownloadShelf(); + int bottom = LayoutExtensionShelf(); + bottom = LayoutDownloadShelf(bottom); LayoutTabContents(top, bottom); // This must be done _after_ we lay out the TabContents since this code calls // back into us to find the bounding box the find bar must be laid out within, @@ -1273,6 +1276,12 @@ void BrowserView::Init() { status_bubble_.reset(new StatusBubbleViews(GetWidget())); + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableExtensions)) { + extension_shelf_ = new ExtensionShelf(browser_.get()); + AddChildView(extension_shelf_); + } + InitSystemMenu(); } @@ -1366,8 +1375,7 @@ void BrowserView::LayoutTabContents(int top, int bottom) { contents_container_->SetBounds(0, top, width(), bottom - top); } -int BrowserView::LayoutDownloadShelf() { - int bottom = height(); +int BrowserView::LayoutDownloadShelf(int bottom) { if (active_download_shelf_) { bool visible = browser_->SupportsWindowFeature( Browser::FEATURE_DOWNLOADSHELF); @@ -1392,6 +1400,21 @@ void BrowserView::LayoutStatusBubble(int top) { kStatusBubbleHeight); } +int BrowserView::LayoutExtensionShelf() { + int bottom = height(); + if (extension_shelf_) { + bool visible = browser_->SupportsWindowFeature( + Browser::FEATURE_EXTENSIONSHELF); + int height = + visible ? extension_shelf_->GetPreferredSize().height() : 0; + extension_shelf_->SetVisible(visible); + extension_shelf_->SetBounds(0, bottom - height, width(), height); + extension_shelf_->Layout(); + bottom -= height; + } + return bottom; +} + bool BrowserView::MaybeShowBookmarkBar(TabContents* contents) { views::View* new_bookmark_bar_view = NULL; if (browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR) diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index c9a19f4..a636883 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -15,12 +15,13 @@ #include "chrome/views/window/window_delegate.h" // NOTE: For more information about the objects and files in this directory, -// view: https://sites.google.com/a/google.com/the-chrome-project/developers/design-documents/browser-window +// view: http://dev.chromium.org/developers/design-documents/browser-window class BookmarkBarView; class Browser; class BrowserToolbarView; class EncodingMenuControllerDelegate; +class ExtensionShelf; class FullscreenExitBubble; class HtmlDialogUIDelegate; class InfoBarContainer; @@ -270,9 +271,11 @@ class BrowserView : public BrowserWindow, void LayoutTabContents(int top, int bottom); // Layout the Download Shelf, returns the coordinate of the top of the\ // control, for laying out the previous control. - int LayoutDownloadShelf(); + int LayoutDownloadShelf(int bottom); // Layout the Status Bubble. void LayoutStatusBubble(int top); + // Layout the Extension Bottom Bar + int LayoutExtensionShelf(); // Prepare to show the Bookmark Bar for the specified TabContents. Returns // true if the Bookmark Bar can be shown (i.e. it's supported for this @@ -397,6 +400,9 @@ class BrowserView : public BrowserWindow, // The timer used to update frames for the Loading Animation. base::RepeatingTimer<BrowserView> loading_animation_timer_; + // A bottom bar for showing extensions. + ExtensionShelf* extension_shelf_; + DISALLOW_COPY_AND_ASSIGN(BrowserView); }; |