Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(943)

Unified Diff: chrome/browser/ui/views/location_bar/zoom_bubble_view.cc

Issue 301733006: Zoom Extension API (chrome) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix javascript test function signature. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
index 80367b88c05a657ac660c074c700deaa4fc231ce..3ab1d2f773bc0faf95a00ffe0d1dd5f24b472a52 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -5,22 +5,29 @@
#include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h"
#include "base/i18n/rtl.h"
+#include "base/strings/stringprintf.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chrome_page_zoom.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/location_bar/zoom_view.h"
#include "chrome/browser/ui/zoom/zoom_controller.h"
+#include "chrome/common/extensions/api/extension_action/action_info.h"
#include "content/public/browser/notification_source.h"
+#include "extensions/common/manifest_handlers/icons_handler.h"
#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/favicon_size.h"
+#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/separator.h"
-#include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/grid_layout.h"
#include "ui/views/layout/layout_constants.h"
#include "ui/views/widget/widget.h"
@@ -51,41 +58,53 @@ void ZoomBubbleView::ShowBubble(content::WebContents* web_contents,
views::View* anchor_view = anchor_to_view ?
browser_view->GetLocationBarView()->zoom_view() : NULL;
- // If the bubble is already showing in this window and its |auto_close_| value
- // is equal to |auto_close|, the bubble can be reused and only the label text
- // needs to be updated.
+ // Find the extension that initiated the zoom change, if any.
+ ZoomController* zoom_controller =
+ ZoomController::FromWebContents(web_contents);
+ const extensions::Extension* extension = zoom_controller->last_extension();
+
+ // If the bubble is already showing in this window, its |auto_close_| value
+ // is equal to |auto_close|, and the zoom change was not initiated by an
+ // extension, then the bubble can be reused and only the label text needs to
+ // be updated.
if (zoom_bubble_ &&
zoom_bubble_->GetAnchorView() == anchor_view &&
- zoom_bubble_->auto_close_ == auto_close) {
+ zoom_bubble_->auto_close_ == auto_close &&
+ !extension) {
zoom_bubble_->Refresh();
- } else {
- // If the bubble is already showing but its |auto_close_| value is not equal
- // to |auto_close|, the bubble's focus properties must change, so the
- // current bubble must be closed and a new one created.
- CloseBubble();
-
- zoom_bubble_ = new ZoomBubbleView(anchor_view,
- web_contents,
- auto_close,
- browser_view->immersive_mode_controller(),
- browser->fullscreen_controller());
-
- // If we do not have an anchor view, parent the bubble to the content area.
- if (!anchor_to_view) {
- zoom_bubble_->set_parent_window(web_contents->GetTopLevelNativeWindow());
- }
+ return;
+ }
+
+ // If the bubble is already showing but its |auto_close_| value is not equal
+ // to |auto_close|, the bubble's focus properties must change, so the
+ // current bubble must be closed and a new one created.
+ CloseBubble();
- views::BubbleDelegateView::CreateBubble(zoom_bubble_);
+ zoom_bubble_ = new ZoomBubbleView(anchor_view,
+ web_contents,
+ auto_close,
+ browser_view->immersive_mode_controller(),
+ browser->fullscreen_controller());
- // Adjust for fullscreen after creation as it relies on the content size.
- if (is_fullscreen)
- zoom_bubble_->AdjustForFullscreen(browser_view->GetBoundsInScreen());
+ // If the zoom change was initiated by an extension, capture the relevent
+ // information from it.
+ if (extension)
+ zoom_bubble_->SetExtensionInfo(extension);
- if (zoom_bubble_->use_focusless())
- zoom_bubble_->GetWidget()->ShowInactive();
- else
- zoom_bubble_->GetWidget()->Show();
- }
+ // If we do not have an anchor view, parent the bubble to the content area.
+ if (!anchor_to_view)
+ zoom_bubble_->set_parent_window(web_contents->GetTopLevelNativeWindow());
+
+ views::BubbleDelegateView::CreateBubble(zoom_bubble_);
+
+ // Adjust for fullscreen after creation as it relies on the content size.
+ if (is_fullscreen)
+ zoom_bubble_->AdjustForFullscreen(browser_view->GetBoundsInScreen());
+
+ if (zoom_bubble_->use_focusless())
+ zoom_bubble_->GetWidget()->ShowInactive();
+ else
+ zoom_bubble_->GetWidget()->Show();
}
// static
@@ -113,6 +132,7 @@ ZoomBubbleView::ZoomBubbleView(
FullscreenController* fullscreen_controller)
: BubbleDelegateView(anchor_view, anchor_view ?
views::BubbleBorder::TOP_RIGHT : views::BubbleBorder::NONE),
+ image_button_(NULL),
label_(NULL),
web_contents_(web_contents),
auto_close_(auto_close),
@@ -150,7 +170,7 @@ void ZoomBubbleView::AdjustForFullscreen(const gfx::Rect& screen_bounds) {
void ZoomBubbleView::Refresh() {
ZoomController* zoom_controller =
ZoomController::FromWebContents(web_contents_);
- int zoom_percent = zoom_controller->zoom_percent();
+ int zoom_percent = zoom_controller->GetZoomPercent();
label_->SetText(
l10n_util::GetStringFUTF16Int(IDS_TOOLTIP_ZOOM, zoom_percent));
StartTimerIfNecessary();
@@ -160,6 +180,50 @@ void ZoomBubbleView::Close() {
GetWidget()->Close();
}
+void ZoomBubbleView::SetExtensionInfo(const extensions::Extension* extension) {
+ DCHECK(extension);
+ extension_info_.id = extension->id();
+ extension_info_.name = extension->name();
+
+ ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ const gfx::ImageSkia& default_extension_icon_image =
+ *rb.GetImageSkiaNamed(IDR_EXTENSIONS_FAVICON);
+ int icon_size = gfx::kFaviconSize;
+
+ // We give first preference to an icon from the extension's icon set that
+ // matches the size of the default. But not all extensions will declare an
+ // icon set, or may not have an icon of the default size (we don't want the
+ // bubble to display, for example, a very large icon). In that case, if there
+ // is a browser-action icon (size-19) this is an acceptable alternative.
+ const ExtensionIconSet& icons = extensions::IconsInfo::GetIcons(extension);
+ bool has_default_sized_icon =
+ !icons.Get(gfx::kFaviconSize, ExtensionIconSet::MATCH_EXACTLY).empty();
+ if (has_default_sized_icon) {
+ extension_info_.icon_image.reset(
+ new extensions::IconImage(web_contents_->GetBrowserContext(),
+ extension,
+ icons,
+ icon_size,
+ default_extension_icon_image,
+ this));
+ return;
+ }
+
+ const extensions::ActionInfo* browser_action =
+ extensions::ActionInfo::GetBrowserActionInfo(extension);
+ if (!browser_action || browser_action->default_icon.empty())
+ return;
+
+ icon_size = browser_action->default_icon.map().begin()->first;
+ extension_info_.icon_image.reset(
+ new extensions::IconImage(web_contents_->GetBrowserContext(),
+ extension,
+ browser_action->default_icon,
+ icon_size,
+ default_extension_icon_image,
+ this));
+}
+
void ZoomBubbleView::StartTimerIfNecessary() {
if (auto_close_) {
if (timer_.IsRunning()) {
@@ -178,6 +242,13 @@ void ZoomBubbleView::StopTimer() {
timer_.Stop();
}
+void ZoomBubbleView::OnExtensionIconImageChanged(
+ extensions::IconImage* /* image */) {
+ image_button_->SetImage(views::Button::STATE_NORMAL,
+ &extension_info_.icon_image->image_skia());
+ image_button_->SchedulePaint();
+}
+
void ZoomBubbleView::OnMouseEntered(const ui::MouseEvent& event) {
set_use_focusless(false);
StopTimer();
@@ -202,28 +273,70 @@ void ZoomBubbleView::OnGestureEvent(ui::GestureEvent* event) {
void ZoomBubbleView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
- chrome_page_zoom::Zoom(web_contents_, content::PAGE_ZOOM_RESET);
+ if (sender == image_button_) {
+ DCHECK(extension_info_.icon_image) << "Invalid button press.";
+ Browser* browser = chrome::FindBrowserWithWebContents(web_contents_);
+ chrome::AddSelectedTabWithURL(
+ browser,
+ GURL(base::StringPrintf("chrome://extensions?id=%s",
+ extension_info_.id.c_str())),
+ content::PAGE_TRANSITION_FROM_API);
+ } else {
+ chrome_page_zoom::Zoom(web_contents_, content::PAGE_ZOOM_RESET);
+ }
}
void ZoomBubbleView::Init() {
- SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
- 0, 0, views::kRelatedControlVerticalSpacing));
+ // Set up the layout of the zoom bubble. A grid layout is used because
+ // sometimes an extension icon is shown next to the zoom label.
+ views::GridLayout* grid_layout = new views::GridLayout(this);
+ SetLayoutManager(grid_layout);
+ views::ColumnSet* columns = grid_layout->AddColumnSet(0);
+ // First row.
+ if (extension_info_.icon_image) {
+ columns->AddColumn(views::GridLayout::CENTER,views::GridLayout::CENTER, 2,
+ views::GridLayout::USE_PREF, 0, 0);
+ }
+ columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
+ views::GridLayout::USE_PREF, 0, 0);
+ grid_layout->StartRow(0, 0);
+
+ // If this zoom change was initiated by an extension, that extension will be
+ // attributed by showing its icon in the zoom bubble.
+ if (extension_info_.icon_image) {
+ image_button_ = new views::ImageButton(this);
+ image_button_->SetTooltipText(l10n_util::GetStringFUTF16(
+ IDS_TOOLTIP_ZOOM_EXTENSION_ICON,
+ base::UTF8ToUTF16(extension_info_.name)));
+ image_button_->SetImage(views::Button::STATE_NORMAL,
+ &extension_info_.icon_image->image_skia());
+ grid_layout->AddView(image_button_);
+ }
+ // Add zoom label with the new zoom percent.
ZoomController* zoom_controller =
ZoomController::FromWebContents(web_contents_);
- int zoom_percent = zoom_controller->zoom_percent();
+ int zoom_percent = zoom_controller->GetZoomPercent();
label_ = new views::Label(
l10n_util::GetStringFUTF16Int(IDS_TOOLTIP_ZOOM, zoom_percent));
label_->SetFontList(
ui::ResourceBundle::GetSharedInstance().GetFontList(
ui::ResourceBundle::MediumFont));
- AddChildView(label_);
+ grid_layout->AddView(label_);
+ // Second row.
+ grid_layout->AddPaddingRow(0, 8);
+ columns = grid_layout->AddColumnSet(1);
+ columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
+ views::GridLayout::USE_PREF, 0, 0);
+ grid_layout->StartRow(0, 1);
+
+ // Add "Reset to Default" button.
views::LabelButton* set_default_button = new views::LabelButton(
this, l10n_util::GetStringUTF16(IDS_ZOOM_SET_DEFAULT));
set_default_button->SetStyle(views::Button::STYLE_BUTTON);
set_default_button->SetHorizontalAlignment(gfx::ALIGN_CENTER);
- AddChildView(set_default_button);
+ grid_layout->AddView(set_default_button);
StartTimerIfNecessary();
}
@@ -249,3 +362,7 @@ void ZoomBubbleView::WindowClosing() {
if (zoom_bubble_ == this)
zoom_bubble_ = NULL;
}
+
+ZoomBubbleView::ZoomBubbleExtensionInfo::ZoomBubbleExtensionInfo() {}
+
+ZoomBubbleView::ZoomBubbleExtensionInfo::~ZoomBubbleExtensionInfo() {}

Powered by Google App Engine
This is Rietveld 408576698