15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/i18n/rtl.h" 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/stringprintf.h" 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chrome_page_zoom.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/browser_tabstrip.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_view.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/location_bar/location_bar_view.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/location_bar/zoom_view.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/zoom/zoom_controller.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/extensions/api/extension_action/action_info.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_source.h" 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/manifest_handlers/icons_handler.h" 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "grit/theme_resources.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/gfx/favicon_size.h" 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/controls/button/image_button.h" 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/controls/button/label_button.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/separator.h" 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/layout/grid_layout.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/layout_constants.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The number of milliseconds the bubble should stay on the screen if it will 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// close automatically. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBubbleCloseDelay = 1500; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The bubble's padding from the screen edge, used in fullscreen. 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kFullscreenPaddingEnd = 20; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ZoomBubbleView* ZoomBubbleView::zoom_bubble_ = NULL; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ZoomBubbleView::ShowBubble(content::WebContents* web_contents, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool auto_close) { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(web_contents); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(browser && browser->window() && browser->fullscreen_controller()); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool is_fullscreen = browser_view->IsFullscreen(); 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool anchor_to_view = !is_fullscreen || 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch browser_view->immersive_mode_controller()->IsRevealed(); 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::View* anchor_view = anchor_to_view ? 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch browser_view->GetLocationBarView()->zoom_view() : NULL; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Find the extension that initiated the zoom change, if any. 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ZoomController* zoom_controller = 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ZoomController::FromWebContents(web_contents); 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const extensions::Extension* extension = zoom_controller->last_extension(); 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If the bubble is already showing in this window and the zoom change was not 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // initiated by an extension, then the bubble can be reused and only the label 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // text needs to be updated. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (zoom_bubble_ && 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) zoom_bubble_->GetAnchorView() == anchor_view && 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch !extension) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zoom_bubble_->Refresh(); 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If the bubble is already showing but in a different tab, the current 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // bubble must be closed and a new one created. 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CloseBubble(); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch zoom_bubble_ = new ZoomBubbleView(anchor_view, 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch web_contents, 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch auto_close, 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch browser_view->immersive_mode_controller(), 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch browser->fullscreen_controller()); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If the zoom change was initiated by an extension, capture the relevent 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // information from it. 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (extension) 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch zoom_bubble_->SetExtensionInfo(extension); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If we do not have an anchor view, parent the bubble to the content area. 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!anchor_to_view) 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch zoom_bubble_->set_parent_window(web_contents->GetTopLevelNativeWindow()); 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch views::BubbleDelegateView::CreateBubble(zoom_bubble_); 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Adjust for fullscreen after creation as it relies on the content size. 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (is_fullscreen) 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch zoom_bubble_->AdjustForFullscreen(browser_view->GetBoundsInScreen()); 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (auto_close) 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch zoom_bubble_->GetWidget()->ShowInactive(); 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch zoom_bubble_->GetWidget()->Show(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ZoomBubbleView::CloseBubble() { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (zoom_bubble_) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zoom_bubble_->Close(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ZoomBubbleView::IsShowing() { 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The bubble may be in the process of closing. 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return zoom_bubble_ != NULL && zoom_bubble_->GetWidget()->IsVisible(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// static 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst ZoomBubbleView* ZoomBubbleView::GetZoomBubbleForTest() { 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return zoom_bubble_; 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochZoomBubbleView::ZoomBubbleView( 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::View* anchor_view, 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content::WebContents* web_contents, 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool auto_close, 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ImmersiveModeController* immersive_mode_controller, 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FullscreenController* fullscreen_controller) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : BubbleDelegateView(anchor_view, anchor_view ? 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::BubbleBorder::TOP_RIGHT : views::BubbleBorder::NONE), 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch image_button_(NULL), 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_(NULL), 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_contents_(web_contents), 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch auto_close_(auto_close), 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch immersive_mode_controller_(immersive_mode_controller) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compensate for built-in vertical padding in the anchor view's image. 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) set_anchor_view_insets(gfx::Insets(5, 0, 5, 0)); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_notify_enter_exit_on_child(true); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Add observers to close the bubble if the fullscreen state or immersive 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // fullscreen revealed state changes. 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Add(this, 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::NOTIFICATION_FULLSCREEN_CHANGED, 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<FullscreenController>(fullscreen_controller)); 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch immersive_mode_controller_->AddObserver(this); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ZoomBubbleView::~ZoomBubbleView() { 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (immersive_mode_controller_) 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch immersive_mode_controller_->RemoveObserver(this); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ZoomBubbleView::AdjustForFullscreen(const gfx::Rect& screen_bounds) { 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (GetAnchorView()) 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(dbeam): should RTL logic be done in views::BubbleDelegateView? 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t bubble_half_width = width() / 2; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int x_pos = base::i18n::IsRTL() ? 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) screen_bounds.x() + bubble_half_width + kFullscreenPaddingEnd : 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) screen_bounds.right() - bubble_half_width - kFullscreenPaddingEnd; 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SetAnchorRect(gfx::Rect(x_pos, screen_bounds.y(), 0, 0)); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ZoomBubbleView::Refresh() { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ZoomController* zoom_controller = 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ZoomController::FromWebContents(web_contents_); 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int zoom_percent = zoom_controller->GetZoomPercent(); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_->SetText( 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringFUTF16Int(IDS_TOOLTIP_ZOOM, zoom_percent)); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTimerIfNecessary(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ZoomBubbleView::Close() { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWidget()->Close(); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ZoomBubbleView::SetExtensionInfo(const extensions::Extension* extension) { 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(extension); 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_info_.id = extension->id(); 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_info_.name = extension->name(); 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const gfx::ImageSkia& default_extension_icon_image = 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *rb.GetImageSkiaNamed(IDR_EXTENSIONS_FAVICON); 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int icon_size = gfx::kFaviconSize; 188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // We give first preference to an icon from the extension's icon set that 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // matches the size of the default. But not all extensions will declare an 191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // icon set, or may not have an icon of the default size (we don't want the 192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // bubble to display, for example, a very large icon). In that case, if there 193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // is a browser-action icon (size-19) this is an acceptable alternative. 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ExtensionIconSet& icons = extensions::IconsInfo::GetIcons(extension); 195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool has_default_sized_icon = 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch !icons.Get(gfx::kFaviconSize, ExtensionIconSet::MATCH_EXACTLY).empty(); 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (has_default_sized_icon) { 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_info_.icon_image.reset( 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new extensions::IconImage(web_contents_->GetBrowserContext(), 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension, 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch icons, 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch icon_size, 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch default_extension_icon_image, 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this)); 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const extensions::ActionInfo* browser_action = 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extensions::ActionInfo::GetBrowserActionInfo(extension); 210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!browser_action || browser_action->default_icon.empty()) 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch icon_size = browser_action->default_icon.map().begin()->first; 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_info_.icon_image.reset( 215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new extensions::IconImage(web_contents_->GetBrowserContext(), 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension, 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch browser_action->default_icon, 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch icon_size, 219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch default_extension_icon_image, 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch this)); 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ZoomBubbleView::StartTimerIfNecessary() { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (auto_close_) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (timer_.IsRunning()) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_.Reset(); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_.Start( 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kBubbleCloseDelay), 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ZoomBubbleView::Close); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ZoomBubbleView::StopTimer() { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_.Stop(); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 241116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ZoomBubbleView::OnExtensionIconImageChanged( 242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extensions::IconImage* /* image */) { 243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch image_button_->SetImage(views::Button::STATE_NORMAL, 244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &extension_info_.icon_image->image_skia()); 245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch image_button_->SchedulePaint(); 246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ZoomBubbleView::OnMouseEntered(const ui::MouseEvent& event) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopTimer(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ZoomBubbleView::OnMouseExited(const ui::MouseEvent& event) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTimerIfNecessary(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ZoomBubbleView::OnGestureEvent(ui::GestureEvent* event) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!zoom_bubble_ || !zoom_bubble_->auto_close_ || 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->type() != ui::ET_GESTURE_TAP) { 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) auto_close_ = false; 2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) StopTimer(); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->SetHandled(); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ZoomBubbleView::ButtonPressed(views::Button* sender, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::Event& event) { 269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (sender == image_button_) { 270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(extension_info_.icon_image) << "Invalid button press."; 271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Browser* browser = chrome::FindBrowserWithWebContents(web_contents_); 272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch chrome::AddSelectedTabWithURL( 273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch browser, 274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GURL(base::StringPrintf("chrome://extensions?id=%s", 275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_info_.id.c_str())), 2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui::PAGE_TRANSITION_FROM_API); 277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch chrome_page_zoom::Zoom(web_contents_, content::PAGE_ZOOM_RESET); 279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ZoomBubbleView::Init() { 283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Set up the layout of the zoom bubble. A grid layout is used because 284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // sometimes an extension icon is shown next to the zoom label. 285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch views::GridLayout* grid_layout = new views::GridLayout(this); 286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SetLayoutManager(grid_layout); 287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch views::ColumnSet* columns = grid_layout->AddColumnSet(0); 288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // First row. 289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (extension_info_.icon_image) { 290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch columns->AddColumn(views::GridLayout::CENTER,views::GridLayout::CENTER, 2, 291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch views::GridLayout::USE_PREF, 0, 0); 292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, 294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch views::GridLayout::USE_PREF, 0, 0); 295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch grid_layout->StartRow(0, 0); 296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If this zoom change was initiated by an extension, that extension will be 298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // attributed by showing its icon in the zoom bubble. 299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (extension_info_.icon_image) { 300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch image_button_ = new views::ImageButton(this); 301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch image_button_->SetTooltipText(l10n_util::GetStringFUTF16( 302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch IDS_TOOLTIP_ZOOM_EXTENSION_ICON, 303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::UTF8ToUTF16(extension_info_.name))); 304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch image_button_->SetImage(views::Button::STATE_NORMAL, 305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &extension_info_.icon_image->image_skia()); 306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch grid_layout->AddView(image_button_); 307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Add zoom label with the new zoom percent. 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ZoomController* zoom_controller = 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ZoomController::FromWebContents(web_contents_); 312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int zoom_percent = zoom_controller->GetZoomPercent(); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_ = new views::Label( 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringFUTF16Int(IDS_TOOLTIP_ZOOM, zoom_percent)); 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) label_->SetFontList( 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::ResourceBundle::GetSharedInstance().GetFontList( 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::ResourceBundle::MediumFont)); 318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch grid_layout->AddView(label_); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Second row. 321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch grid_layout->AddPaddingRow(0, 8); 322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch columns = grid_layout->AddColumnSet(1); 323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, 324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch views::GridLayout::USE_PREF, 0, 0); 325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch grid_layout->StartRow(0, 1); 326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Add "Reset to Default" button. 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) views::LabelButton* set_default_button = new views::LabelButton( 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, l10n_util::GetStringUTF16(IDS_ZOOM_SET_DEFAULT)); 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) set_default_button->SetStyle(views::Button::STYLE_BUTTON); 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) set_default_button->SetHorizontalAlignment(gfx::ALIGN_CENTER); 332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch grid_layout->AddView(set_default_button); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTimerIfNecessary(); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ZoomBubbleView::Observe(int type, 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationSource& source, 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationDetails& details) { 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(type, chrome::NOTIFICATION_FULLSCREEN_CHANGED); 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloseBubble(); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ZoomBubbleView::OnImmersiveRevealStarted() { 345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CloseBubble(); 346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ZoomBubbleView::OnImmersiveModeControllerDestroyed() { 349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch immersive_mode_controller_ = NULL; 350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ZoomBubbleView::WindowClosing() { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |zoom_bubble_| can be a new bubble by this point (as Close(); doesn't 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call this right away). Only set to NULL when it's this bubble. 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (zoom_bubble_ == this) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zoom_bubble_ = NULL; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 359116680a4aac90f2aa7413d9095a592090648e557Ben MurdochZoomBubbleView::ZoomBubbleExtensionInfo::ZoomBubbleExtensionInfo() {} 360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 361116680a4aac90f2aa7413d9095a592090648e557Ben MurdochZoomBubbleView::ZoomBubbleExtensionInfo::~ZoomBubbleExtensionInfo() {} 362