From f689738887b0f2be6174bd03726ac738a2cffa01 Mon Sep 17 00:00:00 2001 From: "sgk@google.com" Date: Fri, 5 Jun 2009 21:42:17 +0000 Subject: Change the name of chrome\browser\views\blocked_popup_container.{cc,h} to blocked_popup_container_view.{cc,h}, to avoid duplication with the same-named files in chrome\browser. BUG=none TEST=successful build Review URL: http://codereview.chromium.org/119253 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17775 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/browser_prefs.cc | 2 +- chrome/browser/views/blocked_popup_container.cc | 395 --------------------- chrome/browser/views/blocked_popup_container.h | 165 --------- .../browser/views/blocked_popup_container_view.cc | 395 +++++++++++++++++++++ .../browser/views/blocked_popup_container_view.h | 165 +++++++++ chrome/browser/views/browser_views.vcproj | 4 +- chrome/chrome.gyp | 4 +- 7 files changed, 565 insertions(+), 565 deletions(-) delete mode 100644 chrome/browser/views/blocked_popup_container.cc delete mode 100644 chrome/browser/views/blocked_popup_container.h create mode 100644 chrome/browser/views/blocked_popup_container_view.cc create mode 100644 chrome/browser/views/blocked_popup_container_view.h (limited to 'chrome') diff --git a/chrome/browser/browser_prefs.cc b/chrome/browser/browser_prefs.cc index bfca089..d208a3f 100644 --- a/chrome/browser/browser_prefs.cc +++ b/chrome/browser/browser_prefs.cc @@ -25,7 +25,7 @@ #if defined(OS_WIN) // TODO(port): whittle this down as we port #include "chrome/browser/task_manager.h" -#include "chrome/browser/views/blocked_popup_container.h" +#include "chrome/browser/views/blocked_popup_container_view.h" #include "chrome/browser/views/frame/browser_view.h" #include "chrome/browser/views/keyword_editor_view.h" #include "chrome/browser/views/page_info_window.h" diff --git a/chrome/browser/views/blocked_popup_container.cc b/chrome/browser/views/blocked_popup_container.cc deleted file mode 100644 index 38fa3a5..0000000 --- a/chrome/browser/views/blocked_popup_container.cc +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright (c) 2008 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. - -// Implementation of BlockedPopupContainer and its corresponding View -// class. The BlockedPopupContainer is the sort of Model class which owns the -// blocked popups' TabContents (but like most Chromium interface code, it there -// isn't a strict Model/View separation), and BlockedPopupContainerView -// presents the user interface controls, creates and manages the popup menu. - -#include "chrome/browser/views/blocked_popup_container.h" - -#include -#include - -#include "app/gfx/canvas.h" -#include "app/gfx/path.h" -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/string_util.h" -#include "chrome/browser/extensions/extension_function_dispatcher.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/common/notification_service.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "views/background.h" -#include "views/controls/button/image_button.h" - -#include "views/controls/scrollbar/native_scroll_bar.h" - -namespace { -// The minimal border around the edge of the notification. -const int kSmallPadding = 2; - -// The background color of the blocked popup notification. -const SkColor kBackgroundColorTop = SkColorSetRGB(255, 242, 183); -const SkColor kBackgroundColorBottom = SkColorSetRGB(250, 230, 145); - -// The border color of the blocked popup notification. This is the same as the -// border around the inside of the tab contents. -const SkColor kBorderColor = SkColorSetRGB(190, 205, 223); -// Thickness of the border. -const int kBorderSize = 1; - -// Duration of the showing/hiding animations. -const int kShowAnimationDurationMS = 200; -const int kHideAnimationDurationMS = 120; -const int kFramerate = 25; - -// So that the MenuButton doesn't change its size as its text changes, during -// construction we feed it the strings it will be displaying, so it can set the -// max text width to the right value. "99" should preallocate enough space for -// all numbers we'd show. -const int kWidestNumber = 99; - -// Rounded corner radius (in pixels). -const int kBackgroundCornerRadius = 4; - -// Rounded corner definition so the top corners are rounded, and the bottom are -// normal 90 degree angles. -const SkScalar kRoundedCornerRad[8] = { - // Top left corner - SkIntToScalar(kBackgroundCornerRadius), - SkIntToScalar(kBackgroundCornerRadius), - // Top right corner - SkIntToScalar(kBackgroundCornerRadius), - SkIntToScalar(kBackgroundCornerRadius), - // Bottom right corner - 0, - 0, - // Bottom left corner - 0, - 0 -}; - -} // namespace - -BlockedPopupContainerView::BlockedPopupContainerView( - BlockedPopupContainerImpl* container) - : container_(container) { - ResourceBundle &resource_bundle = ResourceBundle::GetSharedInstance(); - - // Create a button with a multidigit number to reserve space. - popup_count_label_ = new views::MenuButton( - this, - l10n_util::GetStringF(IDS_POPUPS_BLOCKED_COUNT, - IntToWString(kWidestNumber)), - NULL, true); - // Now set the text to the other possible display string so that the button - // will update its max text width (in case this string is longer). - popup_count_label_->SetText(l10n_util::GetString(IDS_POPUPS_UNBLOCKED)); - popup_count_label_->set_alignment(views::TextButton::ALIGN_CENTER); - AddChildView(popup_count_label_); - - // For now, we steal the Find close button, since it looks OK. - close_button_ = new views::ImageButton(this); - close_button_->SetFocusable(true); - close_button_->SetImage(views::CustomButton::BS_NORMAL, - resource_bundle.GetBitmapNamed(IDR_CLOSE_BAR)); - close_button_->SetImage(views::CustomButton::BS_HOT, - resource_bundle.GetBitmapNamed(IDR_CLOSE_BAR_H)); - close_button_->SetImage(views::CustomButton::BS_PUSHED, - resource_bundle.GetBitmapNamed(IDR_CLOSE_BAR_P)); - AddChildView(close_button_); - - set_background(views::Background::CreateStandardPanelBackground()); - UpdateLabel(); -} - -BlockedPopupContainerView::~BlockedPopupContainerView() { -} - -void BlockedPopupContainerView::UpdateLabel() { - size_t blocked_popups = container_->GetBlockedPopupCount(); - popup_count_label_->SetText((blocked_popups > 0) ? - l10n_util::GetStringF(IDS_POPUPS_BLOCKED_COUNT, - UintToWString(blocked_popups)) : - l10n_util::GetString(IDS_POPUPS_UNBLOCKED)); - Layout(); - SchedulePaint(); -} - -void BlockedPopupContainerView::Paint(gfx::Canvas* canvas) { - // Draw the standard background. - View::Paint(canvas); - - SkRect rect; - rect.set(0, 0, SkIntToScalar(width()), SkIntToScalar(height())); - - // Draw the border - SkPaint border_paint; - border_paint.setFlags(SkPaint::kAntiAlias_Flag); - border_paint.setStyle(SkPaint::kStroke_Style); - border_paint.setColor(kBorderColor); - SkPath border_path; - border_path.addRoundRect(rect, kRoundedCornerRad, SkPath::kCW_Direction); - canvas->drawPath(border_path, border_paint); -} - -void BlockedPopupContainerView::Layout() { - gfx::Size panel_size = GetPreferredSize(); - gfx::Size button_size = close_button_->GetPreferredSize(); - gfx::Size size = popup_count_label_->GetPreferredSize(); - - popup_count_label_->SetBounds(kSmallPadding, kSmallPadding, - size.width(), - size.height()); - - int close_button_padding = - static_cast(ceil(panel_size.height() / 2.0) - - ceil(button_size.height() / 2.0)); - close_button_->SetBounds(width() - button_size.width() - close_button_padding, - close_button_padding, - button_size.width(), - button_size.height()); -} - -gfx::Size BlockedPopupContainerView::GetPreferredSize() { - gfx::Size preferred_size = popup_count_label_->GetPreferredSize(); - preferred_size.Enlarge(close_button_->GetPreferredSize().width(), 0); - // Add padding to all sides of the |popup_count_label_| except the right. - preferred_size.Enlarge(kSmallPadding, 2 * kSmallPadding); - - // Add padding to the left and right side of |close_button_| equal to its - // horizontal/vertical spacing. - gfx::Size button_size = close_button_->GetPreferredSize(); - int close_button_padding = - static_cast(ceil(preferred_size.height() / 2.0) - - ceil(button_size.height() / 2.0)); - preferred_size.Enlarge(2 * close_button_padding, 0); - - return preferred_size; -} - -void BlockedPopupContainerView::ButtonPressed(views::Button* sender) { - if (sender == popup_count_label_) { - launch_menu_.reset(views::Menu::Create(this, views::Menu::TOPLEFT, - container_->GetNativeView())); - - // Set items 1 .. popup_count as individual popups. - size_t popup_count = container_->GetBlockedPopupCount(); - for (size_t i = 0; i < popup_count; ++i) { - std::wstring url, title; - container_->GetURLAndTitleForPopup(i, &url, &title); - // We can't just use the index into container_ here because Menu reserves - // the value 0 as the nop command. - launch_menu_->AppendMenuItem(i + 1, - l10n_util::GetStringF(IDS_POPUP_TITLE_FORMAT, url, title), - views::Menu::NORMAL); - } - - // Set items (kImpossibleNumberOfPopups + 1) .. - // (kImpossibleNumberOfPopups + 1 + hosts.size()) as hosts. - std::vector hosts(container_->GetHosts()); - if (!hosts.empty() && (popup_count > 0)) - launch_menu_->AppendSeparator(); - for (size_t i = 0; i < hosts.size(); ++i) { - launch_menu_->AppendMenuItem( - BlockedPopupContainer::kImpossibleNumberOfPopups + i + 1, - l10n_util::GetStringF(IDS_POPUP_HOST_FORMAT, hosts[i]), - views::Menu::NORMAL); - } - - CPoint cursor_position; - ::GetCursorPos(&cursor_position); - launch_menu_->RunMenuAt(cursor_position.x, cursor_position.y); - } else if (sender == close_button_) { - container_->set_dismissed(); - container_->CloseAll(); - } -} - -bool BlockedPopupContainerView::IsItemChecked(int id) const { - if (id > BlockedPopupContainer::kImpossibleNumberOfPopups) { - return container_->IsHostWhitelisted(static_cast( - id - BlockedPopupContainer::kImpossibleNumberOfPopups - 1)); - } - - return false; -} - -void BlockedPopupContainerView::ExecuteCommand(int id) { - DCHECK_GT(id, 0); - size_t id_size_t = static_cast(id); - if (id_size_t > BlockedPopupContainer::kImpossibleNumberOfPopups) { - // Decrement id since all index based commands have 1 added to them. (See - // ButtonPressed() for detail). - container_->ToggleWhitelistingForHost( - id_size_t - BlockedPopupContainer::kImpossibleNumberOfPopups - 1); - } else { - container_->LaunchPopupAtIndex(id_size_t - 1); - } -} - -BlockedPopupContainerImpl::~BlockedPopupContainerImpl() { -} - -// static -BlockedPopupContainer* BlockedPopupContainer::Create( - TabContents* owner, Profile* profile, const gfx::Point& initial_anchor) { - BlockedPopupContainerImpl* container = - new BlockedPopupContainerImpl(owner, profile->GetPrefs()); - container->Init(initial_anchor); - return container; -} - -void BlockedPopupContainerImpl::GetURLAndTitleForPopup(size_t index, - std::wstring* url, - std::wstring* title) const { - DCHECK(url); - DCHECK(title); - TabContents* tab_contents = blocked_popups_[index].tab_contents; - const GURL& tab_contents_url = tab_contents->GetURL().GetOrigin(); - *url = UTF8ToWide(tab_contents_url.possibly_invalid_spec()); - *title = UTF16ToWideHack(tab_contents->GetTitle()); -} - -std::vector BlockedPopupContainerImpl::GetHosts() const { - std::vector hosts; - for (PopupHosts::const_iterator i(popup_hosts_.begin()); - i != popup_hosts_.end(); ++i) - hosts.push_back(UTF8ToWide(i->first)); - return hosts; -} - -// Overridden from ConstrainedWindow: -void BlockedPopupContainerImpl::Destroy() { - ClearData(); - Close(); -} - -void BlockedPopupContainerImpl::RepositionBlockedPopupContainer( - gfx::NativeView view) { - if (::IsWindow(view)) { - CRect client_rect; - ::GetClientRect(view, &client_rect); - - // TODO(erg): There's no way to detect whether scroll bars are - // visible, so for beta, we're just going to assume that the - // vertical scroll bar is visible, and not care about covering up - // the horizontal scroll bar. Fixing this is half of - // http://b/1118139. - gfx::Point anchor_position( - client_rect.Width() - - views::NativeScrollBar::GetVerticalScrollBarWidth(), - client_rect.Height()); - - RepositionWindowTo(anchor_position); - } -} - -// private: - -BlockedPopupContainerImpl::BlockedPopupContainerImpl(TabContents* owner, - PrefService* prefs) - : BlockedPopupContainer(owner, prefs), - Animation(kFramerate, NULL), - container_view_(NULL), - in_show_animation_(false), - visibility_percentage_(0) { -} - -void BlockedPopupContainerImpl::RepositionWindowTo( - const gfx::Point& anchor_point) { - anchor_point_ = anchor_point; - SetPosition(); -} - -void BlockedPopupContainerImpl::AnimateToState(double state) { - visibility_percentage_ = in_show_animation_ ? state : (1 - state); - SetPosition(); -} - -void BlockedPopupContainerImpl::OnFinalMessage(HWND window) { - GetConstrainingContents(NULL)->WillCloseBlockedPopupContainer(this); - ClearData(); - WidgetWin::OnFinalMessage(window); -} - -void BlockedPopupContainerImpl::OnSize(UINT param, const CSize& size) { - // Set the window region so we have rounded corners on the top. - SkRect rect; - rect.set(0, 0, SkIntToScalar(size.cx), SkIntToScalar(size.cy)); - gfx::Path path; - path.addRoundRect(rect, kRoundedCornerRad, SkPath::kCW_Direction); - SetWindowRgn(path.CreateHRGN(), TRUE); - - ChangeSize(param, size); -} - -void BlockedPopupContainerImpl::Init(const gfx::Point& initial_anchor) { - container_view_ = new BlockedPopupContainerView(this); - container_view_->SetVisible(true); - - set_window_style(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); - WidgetWin::Init(GetConstrainingContents(NULL)->GetNativeView(), gfx::Rect(), - false); - SetContentsView(container_view_); - RepositionWindowTo(initial_anchor); -} - -void BlockedPopupContainerImpl::ShowSelf() { - SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); - if (!Animation::IsAnimating() && visibility_percentage_ < 1.0) { - in_show_animation_ = true; - Animation::SetDuration(kShowAnimationDurationMS); - Animation::Start(); - } -} - -void BlockedPopupContainerImpl::HideSelf() { - in_show_animation_ = false; - Animation::SetDuration(kHideAnimationDurationMS); - Animation::Start(); - BlockedPopupContainer::HideSelf(); -} - -void BlockedPopupContainerImpl::UpdateLabel() { - if (blocked_popups_.empty() && unblocked_popups_.empty()) - HideSelf(); - else - container_view_->UpdateLabel(); -} - -void BlockedPopupContainerImpl::SetPosition() { - gfx::Size size = container_view_->GetPreferredSize(); - int base_x = anchor_point_.x() - size.width(); - int base_y = anchor_point_.y() - size.height(); - // The bounds we report through the automation system are the real bounds; - // the animation is short lived... - bounds_ = gfx::Rect(gfx::Point(base_x, base_y), size); - - int real_height = static_cast(size.height() * visibility_percentage_); - int real_y = anchor_point_.y() - real_height; - - if (real_height > 0) { - int x; - if (l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT) { - // Size this window using the anchor point as top-right corner. - x = base_x; - } else { - // Size this window to the bottom left corner of top client window. In - // Chrome, scrollbars always appear on the right, even for a RTL page or - // when the UI is RTL (see http://crbug.com/6113 for more detail). Thus 0 - // is always a safe value for x-axis. - x = 0; - } - SetWindowPos(HWND_TOP, x, real_y, size.width(), real_height, 0); - container_view_->SchedulePaint(); - } else { - SetWindowPos(HWND_TOP, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW); - } -} diff --git a/chrome/browser/views/blocked_popup_container.h b/chrome/browser/views/blocked_popup_container.h deleted file mode 100644 index 74d3504..0000000 --- a/chrome/browser/views/blocked_popup_container.h +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (c) 2008 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_VIEWS_BLOCKED_POPUP_CONTAINER_H_ -#define CHROME_BROWSER_VIEWS_BLOCKED_POPUP_CONTAINER_H_ - -#include -#include -#include - -#include "app/animation.h" -#include "base/gfx/native_widget_types.h" -#include "base/gfx/rect.h" -#include "chrome/browser/blocked_popup_container.h" -#include "chrome/browser/tab_contents/tab_contents_delegate.h" -#include "views/controls/button/button.h" -#include "views/controls/button/menu_button.h" -#include "views/controls/menu/menu.h" -#include "views/view.h" -#include "views/widget/widget_win.h" - -class BlockedPopupContainerImpl; -class PrefService; -class Profile; -class TabContents; -class TextButton; - -namespace views { -class ImageButton; -} - -// The view presented to the user notifying them of the number of popups -// blocked. This view should only be used inside of BlockedPopupContainer. -class BlockedPopupContainerView : public views::View, - public views::ButtonListener, - public views::Menu::Delegate { - public: - explicit BlockedPopupContainerView(BlockedPopupContainerImpl* container); - ~BlockedPopupContainerView(); - - // Sets the label on the menu button - void UpdateLabel(); - - std::wstring label() const { return popup_count_label_->text(); } - - // Overridden from views::View: - - // Paints our border and background. (Does not paint children.) - virtual void Paint(gfx::Canvas* canvas); - // Sets positions of all child views. - virtual void Layout(); - // Gets the desired size of the popup notification. - virtual gfx::Size GetPreferredSize(); - - // Overridden from views::ButtonListener: - virtual void ButtonPressed(views::Button* sender); - - // Overridden from Menu::Delegate: - - // Displays the status of the "Show Blocked Popup Notification" item. - virtual bool IsItemChecked(int id) const; - // Called after user clicks a menu item. - virtual void ExecuteCommand(int id); - - private: - // Our owner and HWND parent. - BlockedPopupContainerImpl* container_; - - // The button which brings up the popup menu. - views::MenuButton* popup_count_label_; - - // Our "X" button. - views::ImageButton* close_button_; - - // Popup menu shown to user. - scoped_ptr launch_menu_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(BlockedPopupContainerView); -}; - -// Takes ownership of TabContents that are unrequested popup windows and -// presents an interface to the user for launching them. (Or never showing them -// again). -// -// TODO(erg): When this class goes away, whatever is replaced shouldn't -// multiply inherit. -class BlockedPopupContainerImpl : public BlockedPopupContainer, - public Animation, - public views::WidgetWin { - public: - virtual ~BlockedPopupContainerImpl(); - - // Returns the URL and title for popup |index|, used to construct a string for - // display. - void GetURLAndTitleForPopup(size_t index, - std::wstring* url, - std::wstring* title) const; - - // Returns the names of hosts showing popups. - std::vector GetHosts() const; - - virtual void Destroy(); - - virtual void RepositionBlockedPopupContainer(gfx::NativeView view); - - private: - friend class BlockedPopupContainer; - - // Creates a container for a certain TabContents. - BlockedPopupContainerImpl(TabContents* owner, PrefService* prefs); - - // Repositions our blocked popup notification so that the lower right corner - // is at |anchor_point|. - void RepositionWindowTo(const gfx::Point& anchor_point); - - // Overridden from Animation: - // Changes the visibility percentage of the BlockedPopupContainerImpl. This is - // called while animating in or out. - virtual void AnimateToState(double state); - - // Overridden from views::WidgetWin: - - // Alerts our |owner_| that we are closing ourselves. Cleans up any remaining - // blocked popups. - virtual void OnFinalMessage(HWND window); - - // Makes the top corners of the window rounded during resizing events. - virtual void OnSize(UINT param, const CSize& size); - - // Initializes our Views and positions us to the lower right corner of the - // browser window. - void Init(const gfx::Point& initial_anchor); - - // Shows the UI. - virtual void ShowSelf(); - - // Hides the UI portion of the container. - virtual void HideSelf(); - - virtual void UpdateLabel(); - - // Sets our position, based on our |anchor_point_| and on our - // |visibility_percentage_|. This method is called whenever either of those - // change. - void SetPosition(); - - // Our associated view object. - BlockedPopupContainerView* container_view_; - - // True while animating in; false while animating out. - bool in_show_animation_; - - // Percentage of the window to show; used to animate in the notification. - double visibility_percentage_; - - // The bounds to report to the automation system (may not equal our actual - // bounds while animating in or out). - gfx::Rect bounds_; - - // The bottom right corner of where we should appear in our parent window. - gfx::Point anchor_point_; -}; - -#endif diff --git a/chrome/browser/views/blocked_popup_container_view.cc b/chrome/browser/views/blocked_popup_container_view.cc new file mode 100644 index 0000000..edb7c7e --- /dev/null +++ b/chrome/browser/views/blocked_popup_container_view.cc @@ -0,0 +1,395 @@ +// Copyright (c) 2008 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. + +// Implementation of BlockedPopupContainer and its corresponding View +// class. The BlockedPopupContainer is the sort of Model class which owns the +// blocked popups' TabContents (but like most Chromium interface code, it there +// isn't a strict Model/View separation), and BlockedPopupContainerView +// presents the user interface controls, creates and manages the popup menu. + +#include "chrome/browser/views/blocked_popup_container_view.h" + +#include +#include + +#include "app/gfx/canvas.h" +#include "app/gfx/path.h" +#include "app/l10n_util.h" +#include "app/resource_bundle.h" +#include "base/string_util.h" +#include "chrome/browser/extensions/extension_function_dispatcher.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/notification_service.h" +#include "grit/generated_resources.h" +#include "grit/theme_resources.h" +#include "views/background.h" +#include "views/controls/button/image_button.h" + +#include "views/controls/scrollbar/native_scroll_bar.h" + +namespace { +// The minimal border around the edge of the notification. +const int kSmallPadding = 2; + +// The background color of the blocked popup notification. +const SkColor kBackgroundColorTop = SkColorSetRGB(255, 242, 183); +const SkColor kBackgroundColorBottom = SkColorSetRGB(250, 230, 145); + +// The border color of the blocked popup notification. This is the same as the +// border around the inside of the tab contents. +const SkColor kBorderColor = SkColorSetRGB(190, 205, 223); +// Thickness of the border. +const int kBorderSize = 1; + +// Duration of the showing/hiding animations. +const int kShowAnimationDurationMS = 200; +const int kHideAnimationDurationMS = 120; +const int kFramerate = 25; + +// So that the MenuButton doesn't change its size as its text changes, during +// construction we feed it the strings it will be displaying, so it can set the +// max text width to the right value. "99" should preallocate enough space for +// all numbers we'd show. +const int kWidestNumber = 99; + +// Rounded corner radius (in pixels). +const int kBackgroundCornerRadius = 4; + +// Rounded corner definition so the top corners are rounded, and the bottom are +// normal 90 degree angles. +const SkScalar kRoundedCornerRad[8] = { + // Top left corner + SkIntToScalar(kBackgroundCornerRadius), + SkIntToScalar(kBackgroundCornerRadius), + // Top right corner + SkIntToScalar(kBackgroundCornerRadius), + SkIntToScalar(kBackgroundCornerRadius), + // Bottom right corner + 0, + 0, + // Bottom left corner + 0, + 0 +}; + +} // namespace + +BlockedPopupContainerView::BlockedPopupContainerView( + BlockedPopupContainerImpl* container) + : container_(container) { + ResourceBundle &resource_bundle = ResourceBundle::GetSharedInstance(); + + // Create a button with a multidigit number to reserve space. + popup_count_label_ = new views::MenuButton( + this, + l10n_util::GetStringF(IDS_POPUPS_BLOCKED_COUNT, + IntToWString(kWidestNumber)), + NULL, true); + // Now set the text to the other possible display string so that the button + // will update its max text width (in case this string is longer). + popup_count_label_->SetText(l10n_util::GetString(IDS_POPUPS_UNBLOCKED)); + popup_count_label_->set_alignment(views::TextButton::ALIGN_CENTER); + AddChildView(popup_count_label_); + + // For now, we steal the Find close button, since it looks OK. + close_button_ = new views::ImageButton(this); + close_button_->SetFocusable(true); + close_button_->SetImage(views::CustomButton::BS_NORMAL, + resource_bundle.GetBitmapNamed(IDR_CLOSE_BAR)); + close_button_->SetImage(views::CustomButton::BS_HOT, + resource_bundle.GetBitmapNamed(IDR_CLOSE_BAR_H)); + close_button_->SetImage(views::CustomButton::BS_PUSHED, + resource_bundle.GetBitmapNamed(IDR_CLOSE_BAR_P)); + AddChildView(close_button_); + + set_background(views::Background::CreateStandardPanelBackground()); + UpdateLabel(); +} + +BlockedPopupContainerView::~BlockedPopupContainerView() { +} + +void BlockedPopupContainerView::UpdateLabel() { + size_t blocked_popups = container_->GetBlockedPopupCount(); + popup_count_label_->SetText((blocked_popups > 0) ? + l10n_util::GetStringF(IDS_POPUPS_BLOCKED_COUNT, + UintToWString(blocked_popups)) : + l10n_util::GetString(IDS_POPUPS_UNBLOCKED)); + Layout(); + SchedulePaint(); +} + +void BlockedPopupContainerView::Paint(gfx::Canvas* canvas) { + // Draw the standard background. + View::Paint(canvas); + + SkRect rect; + rect.set(0, 0, SkIntToScalar(width()), SkIntToScalar(height())); + + // Draw the border + SkPaint border_paint; + border_paint.setFlags(SkPaint::kAntiAlias_Flag); + border_paint.setStyle(SkPaint::kStroke_Style); + border_paint.setColor(kBorderColor); + SkPath border_path; + border_path.addRoundRect(rect, kRoundedCornerRad, SkPath::kCW_Direction); + canvas->drawPath(border_path, border_paint); +} + +void BlockedPopupContainerView::Layout() { + gfx::Size panel_size = GetPreferredSize(); + gfx::Size button_size = close_button_->GetPreferredSize(); + gfx::Size size = popup_count_label_->GetPreferredSize(); + + popup_count_label_->SetBounds(kSmallPadding, kSmallPadding, + size.width(), + size.height()); + + int close_button_padding = + static_cast(ceil(panel_size.height() / 2.0) - + ceil(button_size.height() / 2.0)); + close_button_->SetBounds(width() - button_size.width() - close_button_padding, + close_button_padding, + button_size.width(), + button_size.height()); +} + +gfx::Size BlockedPopupContainerView::GetPreferredSize() { + gfx::Size preferred_size = popup_count_label_->GetPreferredSize(); + preferred_size.Enlarge(close_button_->GetPreferredSize().width(), 0); + // Add padding to all sides of the |popup_count_label_| except the right. + preferred_size.Enlarge(kSmallPadding, 2 * kSmallPadding); + + // Add padding to the left and right side of |close_button_| equal to its + // horizontal/vertical spacing. + gfx::Size button_size = close_button_->GetPreferredSize(); + int close_button_padding = + static_cast(ceil(preferred_size.height() / 2.0) - + ceil(button_size.height() / 2.0)); + preferred_size.Enlarge(2 * close_button_padding, 0); + + return preferred_size; +} + +void BlockedPopupContainerView::ButtonPressed(views::Button* sender) { + if (sender == popup_count_label_) { + launch_menu_.reset(views::Menu::Create(this, views::Menu::TOPLEFT, + container_->GetNativeView())); + + // Set items 1 .. popup_count as individual popups. + size_t popup_count = container_->GetBlockedPopupCount(); + for (size_t i = 0; i < popup_count; ++i) { + std::wstring url, title; + container_->GetURLAndTitleForPopup(i, &url, &title); + // We can't just use the index into container_ here because Menu reserves + // the value 0 as the nop command. + launch_menu_->AppendMenuItem(i + 1, + l10n_util::GetStringF(IDS_POPUP_TITLE_FORMAT, url, title), + views::Menu::NORMAL); + } + + // Set items (kImpossibleNumberOfPopups + 1) .. + // (kImpossibleNumberOfPopups + 1 + hosts.size()) as hosts. + std::vector hosts(container_->GetHosts()); + if (!hosts.empty() && (popup_count > 0)) + launch_menu_->AppendSeparator(); + for (size_t i = 0; i < hosts.size(); ++i) { + launch_menu_->AppendMenuItem( + BlockedPopupContainer::kImpossibleNumberOfPopups + i + 1, + l10n_util::GetStringF(IDS_POPUP_HOST_FORMAT, hosts[i]), + views::Menu::NORMAL); + } + + CPoint cursor_position; + ::GetCursorPos(&cursor_position); + launch_menu_->RunMenuAt(cursor_position.x, cursor_position.y); + } else if (sender == close_button_) { + container_->set_dismissed(); + container_->CloseAll(); + } +} + +bool BlockedPopupContainerView::IsItemChecked(int id) const { + if (id > BlockedPopupContainer::kImpossibleNumberOfPopups) { + return container_->IsHostWhitelisted(static_cast( + id - BlockedPopupContainer::kImpossibleNumberOfPopups - 1)); + } + + return false; +} + +void BlockedPopupContainerView::ExecuteCommand(int id) { + DCHECK_GT(id, 0); + size_t id_size_t = static_cast(id); + if (id_size_t > BlockedPopupContainer::kImpossibleNumberOfPopups) { + // Decrement id since all index based commands have 1 added to them. (See + // ButtonPressed() for detail). + container_->ToggleWhitelistingForHost( + id_size_t - BlockedPopupContainer::kImpossibleNumberOfPopups - 1); + } else { + container_->LaunchPopupAtIndex(id_size_t - 1); + } +} + +BlockedPopupContainerImpl::~BlockedPopupContainerImpl() { +} + +// static +BlockedPopupContainer* BlockedPopupContainer::Create( + TabContents* owner, Profile* profile, const gfx::Point& initial_anchor) { + BlockedPopupContainerImpl* container = + new BlockedPopupContainerImpl(owner, profile->GetPrefs()); + container->Init(initial_anchor); + return container; +} + +void BlockedPopupContainerImpl::GetURLAndTitleForPopup(size_t index, + std::wstring* url, + std::wstring* title) const { + DCHECK(url); + DCHECK(title); + TabContents* tab_contents = blocked_popups_[index].tab_contents; + const GURL& tab_contents_url = tab_contents->GetURL().GetOrigin(); + *url = UTF8ToWide(tab_contents_url.possibly_invalid_spec()); + *title = UTF16ToWideHack(tab_contents->GetTitle()); +} + +std::vector BlockedPopupContainerImpl::GetHosts() const { + std::vector hosts; + for (PopupHosts::const_iterator i(popup_hosts_.begin()); + i != popup_hosts_.end(); ++i) + hosts.push_back(UTF8ToWide(i->first)); + return hosts; +} + +// Overridden from ConstrainedWindow: +void BlockedPopupContainerImpl::Destroy() { + ClearData(); + Close(); +} + +void BlockedPopupContainerImpl::RepositionBlockedPopupContainer( + gfx::NativeView view) { + if (::IsWindow(view)) { + CRect client_rect; + ::GetClientRect(view, &client_rect); + + // TODO(erg): There's no way to detect whether scroll bars are + // visible, so for beta, we're just going to assume that the + // vertical scroll bar is visible, and not care about covering up + // the horizontal scroll bar. Fixing this is half of + // http://b/1118139. + gfx::Point anchor_position( + client_rect.Width() - + views::NativeScrollBar::GetVerticalScrollBarWidth(), + client_rect.Height()); + + RepositionWindowTo(anchor_position); + } +} + +// private: + +BlockedPopupContainerImpl::BlockedPopupContainerImpl(TabContents* owner, + PrefService* prefs) + : BlockedPopupContainer(owner, prefs), + Animation(kFramerate, NULL), + container_view_(NULL), + in_show_animation_(false), + visibility_percentage_(0) { +} + +void BlockedPopupContainerImpl::RepositionWindowTo( + const gfx::Point& anchor_point) { + anchor_point_ = anchor_point; + SetPosition(); +} + +void BlockedPopupContainerImpl::AnimateToState(double state) { + visibility_percentage_ = in_show_animation_ ? state : (1 - state); + SetPosition(); +} + +void BlockedPopupContainerImpl::OnFinalMessage(HWND window) { + GetConstrainingContents(NULL)->WillCloseBlockedPopupContainer(this); + ClearData(); + WidgetWin::OnFinalMessage(window); +} + +void BlockedPopupContainerImpl::OnSize(UINT param, const CSize& size) { + // Set the window region so we have rounded corners on the top. + SkRect rect; + rect.set(0, 0, SkIntToScalar(size.cx), SkIntToScalar(size.cy)); + gfx::Path path; + path.addRoundRect(rect, kRoundedCornerRad, SkPath::kCW_Direction); + SetWindowRgn(path.CreateHRGN(), TRUE); + + ChangeSize(param, size); +} + +void BlockedPopupContainerImpl::Init(const gfx::Point& initial_anchor) { + container_view_ = new BlockedPopupContainerView(this); + container_view_->SetVisible(true); + + set_window_style(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); + WidgetWin::Init(GetConstrainingContents(NULL)->GetNativeView(), gfx::Rect(), + false); + SetContentsView(container_view_); + RepositionWindowTo(initial_anchor); +} + +void BlockedPopupContainerImpl::ShowSelf() { + SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + if (!Animation::IsAnimating() && visibility_percentage_ < 1.0) { + in_show_animation_ = true; + Animation::SetDuration(kShowAnimationDurationMS); + Animation::Start(); + } +} + +void BlockedPopupContainerImpl::HideSelf() { + in_show_animation_ = false; + Animation::SetDuration(kHideAnimationDurationMS); + Animation::Start(); + BlockedPopupContainer::HideSelf(); +} + +void BlockedPopupContainerImpl::UpdateLabel() { + if (blocked_popups_.empty() && unblocked_popups_.empty()) + HideSelf(); + else + container_view_->UpdateLabel(); +} + +void BlockedPopupContainerImpl::SetPosition() { + gfx::Size size = container_view_->GetPreferredSize(); + int base_x = anchor_point_.x() - size.width(); + int base_y = anchor_point_.y() - size.height(); + // The bounds we report through the automation system are the real bounds; + // the animation is short lived... + bounds_ = gfx::Rect(gfx::Point(base_x, base_y), size); + + int real_height = static_cast(size.height() * visibility_percentage_); + int real_y = anchor_point_.y() - real_height; + + if (real_height > 0) { + int x; + if (l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT) { + // Size this window using the anchor point as top-right corner. + x = base_x; + } else { + // Size this window to the bottom left corner of top client window. In + // Chrome, scrollbars always appear on the right, even for a RTL page or + // when the UI is RTL (see http://crbug.com/6113 for more detail). Thus 0 + // is always a safe value for x-axis. + x = 0; + } + SetWindowPos(HWND_TOP, x, real_y, size.width(), real_height, 0); + container_view_->SchedulePaint(); + } else { + SetWindowPos(HWND_TOP, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW); + } +} diff --git a/chrome/browser/views/blocked_popup_container_view.h b/chrome/browser/views/blocked_popup_container_view.h new file mode 100644 index 0000000..50042d5 --- /dev/null +++ b/chrome/browser/views/blocked_popup_container_view.h @@ -0,0 +1,165 @@ +// Copyright (c) 2008 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_VIEWS_BLOCKED_POPUP_CONTAINER_VIEW_H_ +#define CHROME_BROWSER_VIEWS_BLOCKED_POPUP_CONTAINER_VIEW_H_ + +#include +#include +#include + +#include "app/animation.h" +#include "base/gfx/native_widget_types.h" +#include "base/gfx/rect.h" +#include "chrome/browser/blocked_popup_container.h" +#include "chrome/browser/tab_contents/tab_contents_delegate.h" +#include "views/controls/button/button.h" +#include "views/controls/button/menu_button.h" +#include "views/controls/menu/menu.h" +#include "views/view.h" +#include "views/widget/widget_win.h" + +class BlockedPopupContainerImpl; +class PrefService; +class Profile; +class TabContents; +class TextButton; + +namespace views { +class ImageButton; +} + +// The view presented to the user notifying them of the number of popups +// blocked. This view should only be used inside of BlockedPopupContainer. +class BlockedPopupContainerView : public views::View, + public views::ButtonListener, + public views::Menu::Delegate { + public: + explicit BlockedPopupContainerView(BlockedPopupContainerImpl* container); + ~BlockedPopupContainerView(); + + // Sets the label on the menu button + void UpdateLabel(); + + std::wstring label() const { return popup_count_label_->text(); } + + // Overridden from views::View: + + // Paints our border and background. (Does not paint children.) + virtual void Paint(gfx::Canvas* canvas); + // Sets positions of all child views. + virtual void Layout(); + // Gets the desired size of the popup notification. + virtual gfx::Size GetPreferredSize(); + + // Overridden from views::ButtonListener: + virtual void ButtonPressed(views::Button* sender); + + // Overridden from Menu::Delegate: + + // Displays the status of the "Show Blocked Popup Notification" item. + virtual bool IsItemChecked(int id) const; + // Called after user clicks a menu item. + virtual void ExecuteCommand(int id); + + private: + // Our owner and HWND parent. + BlockedPopupContainerImpl* container_; + + // The button which brings up the popup menu. + views::MenuButton* popup_count_label_; + + // Our "X" button. + views::ImageButton* close_button_; + + // Popup menu shown to user. + scoped_ptr launch_menu_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(BlockedPopupContainerView); +}; + +// Takes ownership of TabContents that are unrequested popup windows and +// presents an interface to the user for launching them. (Or never showing them +// again). +// +// TODO(erg): When this class goes away, whatever is replaced shouldn't +// multiply inherit. +class BlockedPopupContainerImpl : public BlockedPopupContainer, + public Animation, + public views::WidgetWin { + public: + virtual ~BlockedPopupContainerImpl(); + + // Returns the URL and title for popup |index|, used to construct a string for + // display. + void GetURLAndTitleForPopup(size_t index, + std::wstring* url, + std::wstring* title) const; + + // Returns the names of hosts showing popups. + std::vector GetHosts() const; + + virtual void Destroy(); + + virtual void RepositionBlockedPopupContainer(gfx::NativeView view); + + private: + friend class BlockedPopupContainer; + + // Creates a container for a certain TabContents. + BlockedPopupContainerImpl(TabContents* owner, PrefService* prefs); + + // Repositions our blocked popup notification so that the lower right corner + // is at |anchor_point|. + void RepositionWindowTo(const gfx::Point& anchor_point); + + // Overridden from Animation: + // Changes the visibility percentage of the BlockedPopupContainerImpl. This is + // called while animating in or out. + virtual void AnimateToState(double state); + + // Overridden from views::WidgetWin: + + // Alerts our |owner_| that we are closing ourselves. Cleans up any remaining + // blocked popups. + virtual void OnFinalMessage(HWND window); + + // Makes the top corners of the window rounded during resizing events. + virtual void OnSize(UINT param, const CSize& size); + + // Initializes our Views and positions us to the lower right corner of the + // browser window. + void Init(const gfx::Point& initial_anchor); + + // Shows the UI. + virtual void ShowSelf(); + + // Hides the UI portion of the container. + virtual void HideSelf(); + + virtual void UpdateLabel(); + + // Sets our position, based on our |anchor_point_| and on our + // |visibility_percentage_|. This method is called whenever either of those + // change. + void SetPosition(); + + // Our associated view object. + BlockedPopupContainerView* container_view_; + + // True while animating in; false while animating out. + bool in_show_animation_; + + // Percentage of the window to show; used to animate in the notification. + double visibility_percentage_; + + // The bounds to report to the automation system (may not equal our actual + // bounds while animating in or out). + gfx::Rect bounds_; + + // The bottom right corner of where we should appear in our parent window. + gfx::Point anchor_point_; +}; + +#endif diff --git a/chrome/browser/views/browser_views.vcproj b/chrome/browser/views/browser_views.vcproj index d7aa394..b2ddb8b 100644 --- a/chrome/browser/views/browser_views.vcproj +++ b/chrome/browser/views/browser_views.vcproj @@ -460,11 +460,11 @@ >