| 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..8632ea2a9a88a94f7a950189a94e09e36b7c1656 100644
|
| --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
|
| +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
|
| @@ -9,18 +9,22 @@
|
| #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/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,13 +55,20 @@ 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_->Refresh();
|
| + 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
|
| @@ -70,6 +81,12 @@ void ZoomBubbleView::ShowBubble(content::WebContents* web_contents,
|
| browser_view->immersive_mode_controller(),
|
| browser->fullscreen_controller());
|
|
|
| + // If the zoom change was initiated by an extension, capture the relevent
|
| + // information from it.
|
| + if (extension) {
|
| + zoom_bubble_->SetExtensionInfo(extension);
|
| + }
|
| +
|
| // 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());
|
| @@ -113,6 +130,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 +168,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 +178,40 @@ 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 = ResourceBundle::GetSharedInstance();
|
| + const gfx::ImageSkia& default_extension_icon_image =
|
| + *rb.GetImageSkiaNamed(IDR_EXTENSIONS_FAVICON);
|
| + int default_size = default_extension_icon_image.width();
|
| +
|
| + // 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);
|
| + const ExtensionIconSet& action_icon =
|
| + extensions::ActionInfo::GetBrowserActionInfo(extension)
|
| + ->default_icon;
|
| + bool has_default_sized_icon =
|
| + !icons.Get(default_size, ExtensionIconSet::MATCH_EXACTLY).empty();
|
| + if (!has_default_sized_icon && !action_icon.empty())
|
| + default_size = action_icon.map().begin()->first;
|
| + const ExtensionIconSet& icon_set_to_use =
|
| + has_default_sized_icon ? icons : action_icon;
|
| + extension_info_.icon_image.reset(
|
| + new extensions::IconImage(web_contents_->GetBrowserContext(),
|
| + extension,
|
| + icon_set_to_use,
|
| + default_size,
|
| + default_extension_icon_image,
|
| + this));
|
| +}
|
| +
|
| void ZoomBubbleView::StartTimerIfNecessary() {
|
| if (auto_close_) {
|
| if (timer_.IsRunning()) {
|
| @@ -178,6 +230,14 @@ void ZoomBubbleView::StopTimer() {
|
| timer_.Stop();
|
| }
|
|
|
| +void ZoomBubbleView::OnExtensionIconImageChanged(extensions::IconImage* image) {
|
| + DCHECK_EQ(image, extension_info_.icon_image.get()) <<
|
| + "Unknown ImageIcon update.";
|
| + 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 +262,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.get()) << "Invalid button press.";
|
| + Browser* browser = chrome::FindBrowserWithWebContents(web_contents_);
|
| + std::string url("chrome://extensions?id=");
|
| + url += extension_info_.id;
|
| + chrome::AddSelectedTabWithURL(browser,
|
| + GURL(url),
|
| + 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.get()) {
|
| + 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.get()) {
|
| + 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 +351,7 @@ void ZoomBubbleView::WindowClosing() {
|
| if (zoom_bubble_ == this)
|
| zoom_bubble_ = NULL;
|
| }
|
| +
|
| +ZoomBubbleView::ExtensionInfo::ExtensionInfo() {}
|
| +
|
| +ZoomBubbleView::ExtensionInfo::~ExtensionInfo() {}
|
|
|