| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/ui/cocoa/base_bubble_controller.h" | 5 #import "chrome/browser/ui/cocoa/base_bubble_controller.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/mac/bundle_locations.h" | 8 #include "base/mac/bundle_locations.h" |
| 9 #include "base/mac/foundation_util.h" | 9 #include "base/mac/foundation_util.h" |
| 10 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
| 11 #include "base/mac/scoped_nsobject.h" | 11 #include "base/mac/scoped_nsobject.h" |
| 12 #include "base/mac/sdk_forward_declarations.h" | 12 #include "base/mac/sdk_forward_declarations.h" |
| 13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 14 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | 14 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| 15 #import "chrome/browser/ui/cocoa/info_bubble_view.h" | 15 #import "chrome/browser/ui/cocoa/info_bubble_view.h" |
| 16 #import "chrome/browser/ui/cocoa/info_bubble_window.h" | 16 #import "chrome/browser/ui/cocoa/info_bubble_window.h" |
| 17 #import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h" | 17 #import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h" |
| 18 #include "components/bubble/bubble_controller.h" |
| 18 | 19 |
| 19 @interface BaseBubbleController (Private) | 20 @interface BaseBubbleController (Private) |
| 20 - (void)registerForNotifications; | 21 - (void)registerForNotifications; |
| 21 - (void)updateOriginFromAnchor; | 22 - (void)updateOriginFromAnchor; |
| 22 - (void)activateTabWithContents:(content::WebContents*)newContents | 23 - (void)activateTabWithContents:(content::WebContents*)newContents |
| 23 previousContents:(content::WebContents*)oldContents | 24 previousContents:(content::WebContents*)oldContents |
| 24 atIndex:(NSInteger)index | 25 atIndex:(NSInteger)index |
| 25 reason:(int)reason; | 26 reason:(int)reason; |
| 26 - (void)recordAnchorOffset; | 27 - (void)recordAnchorOffset; |
| 27 - (void)parentWindowDidResize:(NSNotification*)notification; | 28 - (void)parentWindowDidResize:(NSNotification*)notification; |
| 28 - (void)parentWindowWillClose:(NSNotification*)notification; | 29 - (void)parentWindowWillClose:(NSNotification*)notification; |
| 29 - (void)parentWindowWillToggleFullScreen:(NSNotification*)notification; | 30 - (void)parentWindowWillToggleFullScreen:(NSNotification*)notification; |
| 30 - (void)closeCleanup; | 31 - (void)closeCleanup; |
| 32 |
| 33 // Temporary methods to decide how to close the bubble controller. |
| 34 // TODO(hcarmona): remove these methods when all bubbles use the BubbleManager. |
| 35 // Notify BubbleManager to close a bubble. |
| 36 - (void)closeBubbleWithReason:(BubbleCloseReason)reason; |
| 37 // Will be a no-op in bubble API because this is handled by the BubbleManager. |
| 38 - (void)closeBubble; |
| 31 @end | 39 @end |
| 32 | 40 |
| 33 @implementation BaseBubbleController | 41 @implementation BaseBubbleController |
| 34 | 42 |
| 35 @synthesize anchorPoint = anchor_; | 43 @synthesize anchorPoint = anchor_; |
| 36 @synthesize bubble = bubble_; | 44 @synthesize bubble = bubble_; |
| 37 @synthesize shouldOpenAsKeyWindow = shouldOpenAsKeyWindow_; | 45 @synthesize shouldOpenAsKeyWindow = shouldOpenAsKeyWindow_; |
| 38 @synthesize shouldCloseOnResignKey = shouldCloseOnResignKey_; | 46 @synthesize shouldCloseOnResignKey = shouldCloseOnResignKey_; |
| 47 @synthesize bubbleReference = bubbleReference_; |
| 39 | 48 |
| 40 - (id)initWithWindowNibPath:(NSString*)nibPath | 49 - (id)initWithWindowNibPath:(NSString*)nibPath |
| 41 parentWindow:(NSWindow*)parentWindow | 50 parentWindow:(NSWindow*)parentWindow |
| 42 anchoredAt:(NSPoint)anchoredAt { | 51 anchoredAt:(NSPoint)anchoredAt { |
| 43 nibPath = [base::mac::FrameworkBundle() pathForResource:nibPath | 52 nibPath = [base::mac::FrameworkBundle() pathForResource:nibPath |
| 44 ofType:@"nib"]; | 53 ofType:@"nib"]; |
| 45 if ((self = [super initWithWindowNibPath:nibPath owner:self])) { | 54 if ((self = [super initWithWindowNibPath:nibPath owner:self])) { |
| 46 [self setParentWindow:parentWindow]; | 55 [self setParentWindow:parentWindow]; |
| 47 anchor_ = anchoredAt; | 56 anchor_ = anchoredAt; |
| 48 shouldOpenAsKeyWindow_ = YES; | 57 shouldOpenAsKeyWindow_ = YES; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 DCHECK_EQ(parentWindow_, [notification object]); | 230 DCHECK_EQ(parentWindow_, [notification object]); |
| 222 NSPoint newOrigin = NSMakePoint(NSMinX([parentWindow_ frame]), | 231 NSPoint newOrigin = NSMakePoint(NSMinX([parentWindow_ frame]), |
| 223 NSMaxY([parentWindow_ frame])); | 232 NSMaxY([parentWindow_ frame])); |
| 224 newOrigin.x -= anchorOffset_.x; | 233 newOrigin.x -= anchorOffset_.x; |
| 225 newOrigin.y -= anchorOffset_.y; | 234 newOrigin.y -= anchorOffset_.y; |
| 226 [self setAnchorPoint:newOrigin]; | 235 [self setAnchorPoint:newOrigin]; |
| 227 } | 236 } |
| 228 | 237 |
| 229 - (void)parentWindowWillClose:(NSNotification*)notification { | 238 - (void)parentWindowWillClose:(NSNotification*)notification { |
| 230 [self setParentWindow:nil]; | 239 [self setParentWindow:nil]; |
| 231 [self close]; | 240 [self closeBubble]; |
| 232 } | 241 } |
| 233 | 242 |
| 234 - (void)parentWindowWillToggleFullScreen:(NSNotification*)notification { | 243 - (void)parentWindowWillToggleFullScreen:(NSNotification*)notification { |
| 235 [self setParentWindow:nil]; | 244 [self setParentWindow:nil]; |
| 236 [self close]; | 245 [self closeBubble]; |
| 237 } | 246 } |
| 238 | 247 |
| 239 - (void)closeCleanup { | 248 - (void)closeCleanup { |
| 240 if (eventTap_) { | 249 if (eventTap_) { |
| 241 [NSEvent removeMonitor:eventTap_]; | 250 [NSEvent removeMonitor:eventTap_]; |
| 242 eventTap_ = nil; | 251 eventTap_ = nil; |
| 243 } | 252 } |
| 244 if (resignationObserver_) { | 253 if (resignationObserver_) { |
| 245 [[NSNotificationCenter defaultCenter] | 254 [[NSNotificationCenter defaultCenter] |
| 246 removeObserver:resignationObserver_ | 255 removeObserver:resignationObserver_ |
| 247 name:NSWindowDidResignKeyNotification | 256 name:NSWindowDidResignKeyNotification |
| 248 object:nil]; | 257 object:nil]; |
| 249 resignationObserver_ = nil; | 258 resignationObserver_ = nil; |
| 250 } | 259 } |
| 251 | 260 |
| 252 tabStripObserverBridge_.reset(); | 261 tabStripObserverBridge_.reset(); |
| 253 } | 262 } |
| 254 | 263 |
| 264 - (void)closeBubbleWithReason:(BubbleCloseReason)reason { |
| 265 if ([self bubbleReference]) |
| 266 [self bubbleReference]->CloseBubble(reason); |
| 267 else |
| 268 [self close]; |
| 269 } |
| 270 |
| 271 - (void)closeBubble { |
| 272 if (![self bubbleReference]) |
| 273 [self close]; |
| 274 } |
| 275 |
| 255 - (void)windowWillClose:(NSNotification*)notification { | 276 - (void)windowWillClose:(NSNotification*)notification { |
| 256 [self closeCleanup]; | 277 [self closeCleanup]; |
| 257 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 278 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 258 [self autorelease]; | 279 [self autorelease]; |
| 259 } | 280 } |
| 260 | 281 |
| 261 // We want this to be a child of a browser window. addChildWindow: | 282 // We want this to be a child of a browser window. addChildWindow: |
| 262 // (called from this function) will bring the window on-screen; | 283 // (called from this function) will bring the window on-screen; |
| 263 // unfortunately, [NSWindowController showWindow:] will also bring it | 284 // unfortunately, [NSWindowController showWindow:] will also bring it |
| 264 // on-screen (but will cause unexpected changes to the window's | 285 // on-screen (but will cause unexpected changes to the window's |
| (...skipping 24 matching lines...) Expand all Loading... |
| 289 DCHECK_EQ([notification object], window); | 310 DCHECK_EQ([notification object], window); |
| 290 | 311 |
| 291 // If the window isn't visible, it is already closed, and this notification | 312 // If the window isn't visible, it is already closed, and this notification |
| 292 // has been sent as part of the closing operation, so no need to close. | 313 // has been sent as part of the closing operation, so no need to close. |
| 293 if (![window isVisible]) | 314 if (![window isVisible]) |
| 294 return; | 315 return; |
| 295 | 316 |
| 296 // Don't close when explicily disabled, or if there's an attached sheet (e.g. | 317 // Don't close when explicily disabled, or if there's an attached sheet (e.g. |
| 297 // Open File dialog). | 318 // Open File dialog). |
| 298 if ([self shouldCloseOnResignKey] && ![window attachedSheet]) { | 319 if ([self shouldCloseOnResignKey] && ![window attachedSheet]) { |
| 299 [self close]; | 320 [self closeBubbleWithReason:BUBBLE_CLOSE_FOCUS_LOST]; |
| 300 return; | 321 return; |
| 301 } | 322 } |
| 302 | 323 |
| 303 // The bubble should not receive key events when it is no longer key window, | 324 // The bubble should not receive key events when it is no longer key window, |
| 304 // so disable sharing parent key state. Share parent key state is only used | 325 // so disable sharing parent key state. Share parent key state is only used |
| 305 // to enable the close/minimize/maximize buttons of the parent window when | 326 // to enable the close/minimize/maximize buttons of the parent window when |
| 306 // the bubble has key state, so disabling it here is safe. | 327 // the bubble has key state, so disabling it here is safe. |
| 307 InfoBubbleWindow* bubbleWindow = | 328 InfoBubbleWindow* bubbleWindow = |
| 308 base::mac::ObjCCastStrict<InfoBubbleWindow>([self window]); | 329 base::mac::ObjCCastStrict<InfoBubbleWindow>([self window]); |
| 309 [bubbleWindow setAllowShareParentKeyState:NO]; | 330 [bubbleWindow setAllowShareParentKeyState:NO]; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 if (![[notif object] isSheet] && | 383 if (![[notif object] isSheet] && |
| 363 [NSApp keyWindow] != [self window]) | 384 [NSApp keyWindow] != [self window]) |
| 364 [self windowDidResignKey:note]; | 385 [self windowDidResignKey:note]; |
| 365 }]; | 386 }]; |
| 366 } | 387 } |
| 367 | 388 |
| 368 // By implementing this, ESC causes the window to go away. | 389 // By implementing this, ESC causes the window to go away. |
| 369 - (IBAction)cancel:(id)sender { | 390 - (IBAction)cancel:(id)sender { |
| 370 // This is not a "real" cancel as potential changes to the radio group are not | 391 // This is not a "real" cancel as potential changes to the radio group are not |
| 371 // undone. That's ok. | 392 // undone. That's ok. |
| 372 [self close]; | 393 [self closeBubbleWithReason:BUBBLE_CLOSE_CANCELED]; |
| 373 } | 394 } |
| 374 | 395 |
| 375 // Takes the |anchor_| point and adjusts the window's origin accordingly. | 396 // Takes the |anchor_| point and adjusts the window's origin accordingly. |
| 376 - (void)updateOriginFromAnchor { | 397 - (void)updateOriginFromAnchor { |
| 377 NSWindow* window = [self window]; | 398 NSWindow* window = [self window]; |
| 378 NSPoint origin = anchor_; | 399 NSPoint origin = anchor_; |
| 379 | 400 |
| 380 switch ([bubble_ alignment]) { | 401 switch ([bubble_ alignment]) { |
| 381 case info_bubble::kAlignArrowToAnchor: { | 402 case info_bubble::kAlignArrowToAnchor: { |
| 382 NSSize offsets = NSMakeSize(info_bubble::kBubbleArrowXOffset + | 403 NSSize offsets = NSMakeSize(info_bubble::kBubbleArrowXOffset + |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 | 443 |
| 423 origin.y -= NSHeight([window frame]); | 444 origin.y -= NSHeight([window frame]); |
| 424 [window setFrameOrigin:origin]; | 445 [window setFrameOrigin:origin]; |
| 425 } | 446 } |
| 426 | 447 |
| 427 - (void)activateTabWithContents:(content::WebContents*)newContents | 448 - (void)activateTabWithContents:(content::WebContents*)newContents |
| 428 previousContents:(content::WebContents*)oldContents | 449 previousContents:(content::WebContents*)oldContents |
| 429 atIndex:(NSInteger)index | 450 atIndex:(NSInteger)index |
| 430 reason:(int)reason { | 451 reason:(int)reason { |
| 431 // The user switched tabs; close. | 452 // The user switched tabs; close. |
| 432 [self close]; | 453 [self closeBubble]; |
| 433 } | 454 } |
| 434 | 455 |
| 435 @end // BaseBubbleController | 456 @end // BaseBubbleController |
| OLD | NEW |