diff options
author | pinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-01 15:50:51 +0000 |
---|---|---|
committer | pinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-01 15:50:51 +0000 |
commit | dd716ab80774cba276e8b5eb61041f9497ddf642 (patch) | |
tree | 1e408f488b0a8b2fb8f38481e042f1f6db12e658 /chrome/browser/cocoa/blocked_popup_container_controller.mm | |
parent | 31a9bdff16526415c4c00aba0cb41cc6654d3e69 (diff) | |
download | chromium_src-dd716ab80774cba276e8b5eb61041f9497ddf642.zip chromium_src-dd716ab80774cba276e8b5eb61041f9497ddf642.tar.gz chromium_src-dd716ab80774cba276e8b5eb61041f9497ddf642.tar.bz2 |
First cut at popup blocking for Mac. Remove ifdefs in cross-platform code. Implement displaying of notification, menu of popups still to come.
BUG=13160
TEST=popup notification should display and popups blocked accordingly. Can close notification widget to prevent more notifications for this tab.
Review URL: http://codereview.chromium.org/150132
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19735 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa/blocked_popup_container_controller.mm')
-rw-r--r-- | chrome/browser/cocoa/blocked_popup_container_controller.mm | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/chrome/browser/cocoa/blocked_popup_container_controller.mm b/chrome/browser/cocoa/blocked_popup_container_controller.mm new file mode 100644 index 0000000..93c3e49 --- /dev/null +++ b/chrome/browser/cocoa/blocked_popup_container_controller.mm @@ -0,0 +1,216 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this +// source code is governed by a BSD-style license that can be found in the +// LICENSE file. + +#import "chrome/browser/cocoa/blocked_popup_container_controller.h" + +#include "app/l10n_util.h" +#include "base/sys_string_conversions.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/tab_contents/tab_contents_view.h" +#include "grit/generated_resources.h" + +#import "chrome/browser/cocoa/background_gradient_view.h" + +// A C++ bridge class that manages the interaction between the C++ interface +// and the Objective-C view controller that implements the popup blocker. +class BlockedPopupContainerViewBridge : public BlockedPopupContainerView { + public: + BlockedPopupContainerViewBridge(BlockedPopupContainerController* controller); + virtual ~BlockedPopupContainerViewBridge(); + + // Overrides from BlockedPopupContainerView + virtual void SetPosition(); + virtual void ShowView(); + virtual void UpdateLabel(); + virtual void HideView(); + virtual void Destroy(); + + private: + BlockedPopupContainerController* controller_; // Weak, owns us. +}; + +@interface BlockedPopupContainerController(Private) +- (void)initPopupView; +- (NSView*)containingView; +@end + +@implementation BlockedPopupContainerController + +// Initialize with the given popup container. Creates the C++ bridge object +// used to represent the "view". +- (id)initWithContainer:(BlockedPopupContainer*)container { + if ((self = [super init])) { + container_ = container; + bridge_.reset(new BlockedPopupContainerViewBridge(self)); + [self initPopupView]; + } + return self; +} + +- (void)dealloc { + [view_ removeFromSuperview]; + [super dealloc]; +} + +- (IBAction)closePopup:(id)sender { + container_->set_dismissed(); + container_->CloseAll(); +} + +// Create and initialize the popup view and its label, close box, etc. +- (void)initPopupView { + static const float kWidth = 200.0; + static const float kHeight = 20.0; + static const float kCloseBoxSize = 16.0; + static const float kCloseBoxPaddingY = 2.0; + static const float kLabelPaddingX = 5.0; + + // Create it below the parent's bottom edge so we can animate it into place. + NSRect startFrame = NSMakeRect(0.0, -kHeight, kWidth, kHeight); + view_.reset([[BackgroundGradientView alloc] initWithFrame:startFrame]); + [view_ setAutoresizingMask:NSViewMinXMargin | NSViewMaxYMargin]; + + // Create the text label and position it. We'll resize it later when the + // label gets updated. The view owns the label, we only hold a weak reference. + NSRect labelFrame = NSMakeRect(kLabelPaddingX, + 0, + startFrame.size.width - kCloseBoxSize, + startFrame.size.height); + label_ = [[[NSTextField alloc] initWithFrame:labelFrame] autorelease]; + [label_ setSelectable:NO]; + [label_ setAutoresizingMask:NSViewWidthSizable]; + [label_ setBordered:NO]; + [label_ setBezeled:NO]; + [label_ setDrawsBackground:NO]; + [view_ addSubview:label_]; + + // Create the close box and position at the left of the view. + NSRect closeFrame = NSMakeRect(startFrame.size.width - kCloseBoxSize, + kCloseBoxPaddingY, + kCloseBoxSize, + kCloseBoxSize); + NSButton* close = [[[NSButton alloc] initWithFrame:closeFrame] autorelease]; + [close setAutoresizingMask:NSViewMinXMargin]; + [close setImage:[NSImage imageNamed:@"close_bar"]]; + [close setAlternateImage:[NSImage imageNamed:@"close_bar_p"]]; + [close setBordered:NO]; + [close setTarget:self]; + [close setAction:@selector(closePopup:)]; + [view_ addSubview:close]; +} + +// Returns the C++ brige object. +- (BlockedPopupContainerView*)bridge { + return bridge_.get(); +} + +// Returns the parent of the RWHVMac. We insert our popup blocker as a sibling +// so that it stays around as the RWHVMac is created/destroyed during +// navigation. +- (NSView*)containingView { + return container_->GetConstrainingContents(NULL)->view()->GetNativeView(); +} + +- (void)show { + const float kLeftPadding = 20; // Leave room for the scrollbar. + + // No need to do anything if it's already on screen. + if ([view_ superview]) return; + + // Position the view at the bottom right corner, always leaving room for the + // scrollbar. This is what window does. It also doesn't care about covering + // up the horizontal scrollbar. + NSView* parent = [self containingView]; + NSRect frame = [view_ frame]; + frame.origin.x = [parent frame].size.width - frame.size.width - kLeftPadding; + [view_ setFrame:frame]; + + // Add the view and animate it sliding up into view. + [parent addSubview:view_.get()]; + frame.origin.y = 0; + [[view_ animator] setFrame:frame]; +} + +- (void)hide { + [view_ removeFromSuperview]; +} + +// Resize the view based on the new label contents. The autoresize mask will +// take care of resizing everything else. +- (void)resizeWithLabel:(NSString*)label { +#if 0 +// TODO(pinkerton): fix this once the popup gets put in. + NSSize stringSize = [label sizeWithAttributes:nil]; + NSRect frame = [view_ frame]; + float originalWidth = frame.size.width; + frame.size.width = stringSize.width + 16 + 5; + frame.origin.x -= frame.size.width - originalWidth; + [view_ setFrame:frame]; +#endif +} + +- (void)update { + size_t blockedPopups = container_->GetBlockedPopupCount(); + NSString* label = nil; + if (blockedPopups) { + label = base::SysUTF16ToNSString( + l10n_util::GetStringFUTF16(IDS_POPUPS_BLOCKED_COUNT, + UintToString16(blockedPopups))); + } else { + label = base::SysUTF16ToNSString( + l10n_util::GetStringUTF16(IDS_POPUPS_UNBLOCKED)); + } + [self resizeWithLabel:label]; + [label_ setStringValue:label]; +} + +- (NSView*)view { + return view_.get(); +} + +- (NSView*)label { + return label_; +} + +@end + +//--------------------------------------------------------------------------- + +BlockedPopupContainerView* BlockedPopupContainerView::Create( + BlockedPopupContainer* container) { + // We "leak" |blocker| for now, we'll release it when the bridge class + // gets a Destroy() message. + BlockedPopupContainerController* blocker = + [[BlockedPopupContainerController alloc] initWithContainer:container]; + return [blocker bridge]; +} + +BlockedPopupContainerViewBridge::BlockedPopupContainerViewBridge( + BlockedPopupContainerController* controller) { + controller_ = controller; +} + +BlockedPopupContainerViewBridge::~BlockedPopupContainerViewBridge() { +} + +void BlockedPopupContainerViewBridge::SetPosition() { + // Doesn't ever get called, also a no-op on GTK. + NOTIMPLEMENTED(); +} + +void BlockedPopupContainerViewBridge::ShowView() { + [controller_ show]; +} + +void BlockedPopupContainerViewBridge::UpdateLabel() { + [controller_ update]; +} + +void BlockedPopupContainerViewBridge::HideView() { + [controller_ hide]; +} + +void BlockedPopupContainerViewBridge::Destroy() { + [controller_ autorelease]; +} |