Index: chrome/browser/cocoa/base_bubble_controller.mm |
diff --git a/chrome/browser/cocoa/base_bubble_controller.mm b/chrome/browser/cocoa/base_bubble_controller.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b155a4f75c47cdca1d61ae775dc2d9879b6cfbf4 |
--- /dev/null |
+++ b/chrome/browser/cocoa/base_bubble_controller.mm |
@@ -0,0 +1,123 @@ |
+// Copyright (c) 2010 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/base_bubble_controller.h" |
+ |
+#include "app/l10n_util.h" |
+#include "base/logging.h" |
+#include "base/mac_util.h" |
+#include "base/string_util.h" |
+#import "chrome/browser/cocoa/info_bubble_view.h" |
+#include "grit/generated_resources.h" |
+ |
+@implementation BaseBubbleController |
+ |
+@synthesize bubble = bubble_; |
+ |
+- (id)initWithWindowNibPath:(NSString*)nibPath |
+ parentWindow:(NSWindow*)parentWindow |
+ anchoredAt:(NSPoint)anchoredAt { |
+ nibPath = [mac_util::MainAppBundle() pathForResource:nibPath |
+ ofType:@"nib"]; |
+ if ((self = [super initWithWindowNibPath:nibPath owner:self])) { |
+ parentWindow_ = parentWindow; |
+ anchor_ = anchoredAt; |
+ |
+ // Watch to see if the parent window closes, and if so, close this one. |
+ NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; |
+ [center addObserver:self |
+ selector:@selector(parentWindowWillClose:) |
+ name:NSWindowWillCloseNotification |
+ object:parentWindow_]; |
+ } |
+ return self; |
+} |
+ |
+- (id)initWithWindowNibPath:(NSString*)nibPath |
+ relativeToView:(NSView*)view |
+ offset:(NSPoint)offset { |
+ DCHECK([view window]); |
+ NSWindow* window = [view window]; |
+ NSRect bounds = [view convertRect:[view bounds] toView:nil]; |
+ NSPoint anchor = NSMakePoint(NSMinX(bounds) + offset.x, |
+ NSMinY(bounds) + offset.y); |
+ anchor = [window convertBaseToScreen:anchor]; |
+ return [self initWithWindowNibPath:nibPath |
+ parentWindow:window |
+ anchoredAt:anchor]; |
+} |
+ |
+ |
+- (void)awakeFromNib { |
+ // Check all connections have been made in Interface Builder. |
+ DCHECK([self window]); |
+ DCHECK(bubble_); |
+ DCHECK_EQ(self, [[self window] delegate]); |
+ |
+ [bubble_ setBubbleType:info_bubble::kWhiteInfoBubble]; |
+ [bubble_ setArrowLocation:info_bubble::kTopRight]; |
+} |
+ |
+- (void)dealloc { |
+ [[NSNotificationCenter defaultCenter] removeObserver:self]; |
+ [super dealloc]; |
+} |
+ |
+- (void)parentWindowWillClose:(NSNotification*)notification { |
+ [self close]; |
+} |
+ |
+- (void)windowWillClose:(NSNotification*)notification { |
+ // We caught a close so we don't need to watch for the parent closing. |
+ [[NSNotificationCenter defaultCenter] removeObserver:self]; |
+ [self autorelease]; |
+} |
+ |
+// We want this to be a child of a browser window. addChildWindow: |
+// (called from this function) will bring the window on-screen; |
+// unfortunately, [NSWindowController showWindow:] will also bring it |
+// on-screen (but will cause unexpected changes to the window's |
+// position). We cannot have an addChildWindow: and a subsequent |
+// showWindow:. Thus, we have our own version. |
+- (void)showWindow:(id)sender { |
+ NSWindow* window = [self window]; // completes nib load |
jeremy
2010/06/27 12:46:42
nit: Completes nib load.
|
+ |
+ NSPoint origin = anchor_; |
+ NSSize offsets = NSMakeSize(info_bubble::kBubbleArrowXOffset + |
+ info_bubble::kBubbleArrowWidth / 2.0, 0); |
+ offsets = [[parentWindow_ contentView] convertSize:offsets toView:nil]; |
+ origin.x += offsets.width; |
+ if ([bubble_ arrowLocation] == info_bubble::kTopRight) |
+ origin.x -= NSWidth([window frame]); |
+ origin.y -= NSHeight([window frame]); |
+ [window setFrameOrigin:origin]; |
+ [parentWindow_ addChildWindow:window ordered:NSWindowAbove]; |
+ [window makeKeyAndOrderFront:self]; |
+} |
+ |
+- (void)close { |
+ [parentWindow_ removeChildWindow:[self window]]; |
+ [super close]; |
+} |
+ |
+// The controller is the delegate of the window so it receives did resign key |
+// notifications. When key is resigned mirror Windows behavior and close the |
+// window. |
+- (void)windowDidResignKey:(NSNotification*)notification { |
+ NSWindow* window = [self window]; |
+ DCHECK_EQ([notification object], window); |
+ if ([window isVisible]) { |
+ // If the window isn't visible, it is already closed, and this notification |
+ // has been sent as part of the closing operation, so no need to close. |
+ [self close]; |
+ } |
+} |
+ |
+// By implementing this, ESC causes the window to go away. |
+- (IBAction)cancel:(id)sender { |
+ // This is not a "real" cancel as potential changes to the radio group are not |
+ // undone. That's ok. |
jeremy
2010/06/27 12:46:42
Could you expand this comment: which radio group?
|
+ [self close]; |
+} |
+@end // BaseBubbleController |