summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/location_bar_view.cc
diff options
context:
space:
mode:
authorfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-01 22:02:34 +0000
committerfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-01 22:02:34 +0000
commitf7f3a5f86a24f65666284802b51d0eaa5c9d7741 (patch)
tree5605992d68c1b48fe47f7fbee560dca7cda6693b /chrome/browser/views/location_bar_view.cc
parent32d371758f777380486f9c8ef28b1faca37ab26c (diff)
downloadchromium_src-f7f3a5f86a24f65666284802b51d0eaa5c9d7741.zip
chromium_src-f7f3a5f86a24f65666284802b51d0eaa5c9d7741.tar.gz
chromium_src-f7f3a5f86a24f65666284802b51d0eaa5c9d7741.tar.bz2
This is the first part of the PageAction implementation. More work is required, but this is a good checkpoint.
Design doc: http://dev.chromium.org/developers/design-documents/extensions/page-actions-api This checkin only covers Tab scoped page actions (not type "permanent"). It works end to end (if you have an extension that supplies the page action info -- I created an RSS page action that links to Google Reader). Please note that TabIndex is hard coded to 0 until the extension system can provide the tab id to the extensions (which I understand is in progress). This means that page action(s) only show up for the first tab in the tabstrip. :) BUG=None TEST=There is a unit test for the API, but apart from that it is not possible to test this manually without writing an extension that adds a PageAction. My RSS page action is not ready to be checked in but I can provide it if there is interest in a sneak preview during review/QA. Review URL: http://codereview.chromium.org/99253 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15105 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views/location_bar_view.cc')
-rw-r--r--chrome/browser/views/location_bar_view.cc161
1 files changed, 158 insertions, 3 deletions
diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc
index 3311a52..62c7a8d 100644
--- a/chrome/browser/views/location_bar_view.cc
+++ b/chrome/browser/views/location_bar_view.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -12,6 +12,9 @@
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/command_updater.h"
+#include "chrome/browser/extensions/extension_browser_event_router.h"
+#include "chrome/browser/extensions/extension_tabs_module.h"
+#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_model.h"
@@ -102,6 +105,10 @@ LocationBarView::LocationBarView(Profile* profile,
}
}
+LocationBarView::~LocationBarView() {
+ DeletePageActionViews();
+}
+
bool LocationBarView::IsInitialized() const {
return location_entry_view_ != NULL;
}
@@ -178,6 +185,7 @@ void LocationBarView::Init() {
void LocationBarView::Update(const TabContents* tab_for_state_restoring) {
SetSecurityIcon(model_->GetIcon());
SetRssIconVisibility(model_->GetFeedList().get());
+ RefreshPageActionViews();
std::wstring info_text, info_tooltip;
SkColor text_color;
model_->GetInfoText(&info_text, &text_color, &info_tooltip);
@@ -193,6 +201,13 @@ void LocationBarView::UpdateFeedIcon() {
SchedulePaint();
}
+void LocationBarView::UpdatePageActions() {
+ RefreshPageActionViews();
+
+ Layout();
+ SchedulePaint();
+}
+
void LocationBarView::Focus() {
::SetFocus(location_entry_->m_hWnd);
}
@@ -346,10 +361,18 @@ void LocationBarView::DoLayout(const bool force_layout) {
int entry_width = width() - (kEntryPadding * 2);
+ gfx::Size page_action_size;
+ for (size_t i = 0; i < page_action_image_views_.size(); i++) {
+ if (page_action_image_views_[i]->IsVisible()) {
+ page_action_size = page_action_image_views_[i]->GetPreferredSize();
+ entry_width -= (page_action_size.width() + kInnerPadding) *
+ page_action_image_views_.size();
+ }
+ }
gfx::Size rss_image_size;
if (rss_image_view_.IsVisible()) {
rss_image_size = rss_image_view_.GetPreferredSize();
- entry_width -= rss_image_size.width();
+ entry_width -= rss_image_size.width() + kInnerPadding;
}
gfx::Size security_image_size;
if (security_image_view_.IsVisible()) {
@@ -383,6 +406,19 @@ void LocationBarView::DoLayout(const bool force_layout) {
}
const int info_label_width = info_label_size.width() ?
info_label_size.width() + kInnerPadding : 0;
+
+ int offset = width() - kEntryPadding - info_label_width -
+ security_image_size.width();
+
+ for (size_t i = 0; i < page_action_image_views_.size(); i++) {
+ if (page_action_image_views_[i]->IsVisible()) {
+ page_action_size = page_action_image_views_[i]->GetPreferredSize();
+ offset -= page_action_size.width();
+ page_action_image_views_[i]->SetBounds(offset, location_y,
+ page_action_size.width(),
+ location_height);
+ }
+ }
if (rss_image_view_.IsVisible()) {
rss_image_view_.SetBounds(width() - kEntryPadding -
info_label_width -
@@ -529,6 +565,64 @@ void LocationBarView::SetRssIconVisibility(FeedList* feeds) {
rss_image_view_.SetVisible(false);
}
+void LocationBarView::DeletePageActionViews() {
+ if (!page_action_image_views_.empty()) {
+ for (size_t i = 0; i < page_action_image_views_.size(); ++i)
+ RemoveChildView(page_action_image_views_[i]);
+ STLDeleteContainerPointers(page_action_image_views_.begin(),
+ page_action_image_views_.end());
+ page_action_image_views_.clear();
+ }
+}
+
+std::vector<PageAction*> LocationBarView::GetPageActions() {
+ std::vector<PageAction*> result;
+
+ // Query the extension system to see how many page actions we have.
+ // TODO(finnur): Sort the page icons in some meaningful way.
+ const ExtensionList* extensions =
+ profile_->GetExtensionsService()->extensions();
+ for (ExtensionList::const_iterator iter = extensions->begin();
+ iter != extensions->end(); ++iter) {
+ const PageActionMap& page_actions = (*iter)->page_actions();
+ for (PageActionMap::const_iterator i(page_actions.begin());
+ i != page_actions.end(); ++i) {
+ result.push_back(i->second);
+ }
+ }
+
+ return result;
+}
+
+void LocationBarView::RefreshPageActionViews() {
+ std::vector<PageAction*> page_actions = GetPageActions();
+
+ // On startup we sometimes haven't loaded any extensions. This makes sure
+ // we catch up when the extensions (and any page actions) load.
+ if (page_actions.size() != page_action_image_views_.size()) {
+ DeletePageActionViews(); // Delete the old views (if any).
+
+ page_action_image_views_.resize(page_actions.size());
+
+ for (size_t i = 0; i < page_actions.size(); ++i) {
+ page_action_image_views_[i] =
+ new PageActionImageView(this, profile_, page_actions[i]);
+ page_action_image_views_[i]->SetVisible(false);
+ page_action_image_views_[i]->SetParentOwned(false);
+ AddChildView(page_action_image_views_[i]);
+ }
+ }
+
+ TabContents* contents = delegate_->GetTabContents();
+ if (!page_action_image_views_.empty() && contents) {
+ int tab_id = ExtensionTabUtil::GetTabId(contents);
+ GURL url = GURL(model_->GetText());
+
+ for (size_t i = 0; i < page_action_image_views_.size(); i++)
+ page_action_image_views_[i]->UpdateVisibility(tab_id, url);
+ }
+}
+
void LocationBarView::SetInfoText(const std::wstring& text,
SkColor text_color,
const std::wstring& tooltip_text) {
@@ -840,7 +934,7 @@ class LocationBarView::ShowInfoBubbleTask : public Task {
LocationBarView::LocationBarImageView* image_view_;
bool cancelled_;
- DISALLOW_EVIL_CONSTRUCTORS(ShowInfoBubbleTask);
+ DISALLOW_COPY_AND_ASSIGN(ShowInfoBubbleTask);
};
LocationBarView::ShowInfoBubbleTask::ShowInfoBubbleTask(
@@ -1078,6 +1172,67 @@ void LocationBarView::RssImageView::ShowInfoBubble() {
ShowInfoBubbleImpl(text, text_color);
}
+// PageActionImageView----------------------------------------------------------
+
+LocationBarView::PageActionImageView::PageActionImageView(
+ LocationBarView* owner,
+ Profile* profile,
+ const PageAction* page_action)
+ : owner_(owner),
+ profile_(profile),
+ page_action_(page_action),
+ LocationBarImageView() {
+ // The first thing we do is try to set the image from the PageAction icon.
+ if (page_action->icon_path().empty()) {
+ NOTREACHED();
+ return; // Need icon path to continue.
+ }
+
+ IconManager* im = g_browser_process->icon_manager();
+
+ SkBitmap* icon = im->LookupIcon(page_action->icon_path(),
+ IconLoader::SMALL);
+ if (icon) {
+ ImageView::SetImage(icon);
+ } else {
+ // Ask the Icon Manager to load the icon (happens on the File thread).
+ IconManager::Handle h = im->LoadIcon(page_action->icon_path(),
+ IconLoader::SMALL, &icon_consumer_,
+ NewCallback(this, &LocationBarView::PageActionImageView::OnIconLoaded));
+ }
+}
+
+LocationBarView::PageActionImageView::~PageActionImageView() {
+ icon_consumer_.CancelAllRequests();
+}
+
+bool LocationBarView::PageActionImageView::OnMousePressed(
+ const views::MouseEvent& event) {
+ // Our PageAction icon was clicked on, notify proper authorities.
+ ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
+ profile_, page_action_->id(), current_tab_id_, current_url_.spec());
+ return true;
+}
+
+void LocationBarView::PageActionImageView::ShowInfoBubble() {
+ SkColor text_color = SK_ColorBLACK;
+ ShowInfoBubbleImpl(ASCIIToWide(page_action_->tooltip()), text_color);
+}
+
+void LocationBarView::PageActionImageView::UpdateVisibility(
+ int tab_id, GURL url) {
+ current_tab_id_ = tab_id;
+ current_url_ = url;
+
+ SetVisible(page_action_->IsActive(current_tab_id_, current_url_));
+}
+
+void LocationBarView::PageActionImageView::OnIconLoaded(
+ IconManager::Handle handle, SkBitmap* icon) {
+ ImageView::SetImage(icon);
+ owner_->UpdatePageActions();
+}
+
bool LocationBarView::OverrideAccelerator(
const views::Accelerator& accelerator) {
return location_entry_->OverrideAccelerator(accelerator);