| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 #include "chrome/browser/cocoa/status_bubble_mac.h" | 5 #include "chrome/browser/cocoa/status_bubble_mac.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "app/gfx/text_elider.h" | 9 #include "app/gfx/text_elider.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 url_text_(nil), | 100 url_text_(nil), |
| 101 state_(kBubbleHidden), | 101 state_(kBubbleHidden), |
| 102 immediate_(false) { | 102 immediate_(false) { |
| 103 } | 103 } |
| 104 | 104 |
| 105 StatusBubbleMac::~StatusBubbleMac() { | 105 StatusBubbleMac::~StatusBubbleMac() { |
| 106 Hide(); | 106 Hide(); |
| 107 | 107 |
| 108 if (window_) { | 108 if (window_) { |
| 109 [[[window_ animationForKey:kFadeAnimationKey] delegate] invalidate]; | 109 [[[window_ animationForKey:kFadeAnimationKey] delegate] invalidate]; |
| 110 [parent_ removeChildWindow:window_]; | 110 Detach(); |
| 111 [window_ release]; | 111 [window_ release]; |
| 112 window_ = nil; | 112 window_ = nil; |
| 113 } | 113 } |
| 114 } | 114 } |
| 115 | 115 |
| 116 void StatusBubbleMac::SetStatus(const std::wstring& status) { | 116 void StatusBubbleMac::SetStatus(const std::wstring& status) { |
| 117 Create(); | 117 Create(); |
| 118 | 118 |
| 119 SetText(status, false); | 119 SetText(status, false); |
| 120 } | 120 } |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 [animation autorelease]; | 326 [animation autorelease]; |
| 327 StatusBubbleAnimationDelegate* animation_delegate = | 327 StatusBubbleAnimationDelegate* animation_delegate = |
| 328 [[StatusBubbleAnimationDelegate alloc] initWithStatusBubble:this]; | 328 [[StatusBubbleAnimationDelegate alloc] initWithStatusBubble:this]; |
| 329 [animation_delegate autorelease]; | 329 [animation_delegate autorelease]; |
| 330 [animation setDelegate:animation_delegate]; | 330 [animation setDelegate:animation_delegate]; |
| 331 NSMutableDictionary* animation_dictionary = | 331 NSMutableDictionary* animation_dictionary = |
| 332 [NSMutableDictionary dictionaryWithDictionary:[window_ animations]]; | 332 [NSMutableDictionary dictionaryWithDictionary:[window_ animations]]; |
| 333 [animation_dictionary setObject:animation forKey:kFadeAnimationKey]; | 333 [animation_dictionary setObject:animation forKey:kFadeAnimationKey]; |
| 334 [window_ setAnimations:animation_dictionary]; | 334 [window_ setAnimations:animation_dictionary]; |
| 335 | 335 |
| 336 Attach(); | 336 // Don't |Attach()| since we don't know the appropriate state; let the |
| 337 // |SetState()| call do that. |
| 337 | 338 |
| 338 [view setCornerFlags:kRoundedTopRightCorner]; | 339 [view setCornerFlags:kRoundedTopRightCorner]; |
| 339 MouseMoved(gfx::Point(), false); | 340 MouseMoved(gfx::Point(), false); |
| 340 } | 341 } |
| 341 | 342 |
| 342 void StatusBubbleMac::Attach() { | 343 void StatusBubbleMac::Attach() { |
| 343 // If the parent window is offscreen when the child is added, the child will | 344 // This method may be called several times during the process of creating or |
| 344 // never be displayed, even when the parent moves on-screen. This method | 345 // showing a status bubble to attach the bubble to its parent window. |
| 345 // may be called several times during the process of creating or showing a | 346 if (!is_attached()) |
| 346 // status bubble to attach the bubble to its parent window. | |
| 347 if (![window_ parentWindow] && [parent_ isVisible]) | |
| 348 [parent_ addChildWindow:window_ ordered:NSWindowAbove]; | 347 [parent_ addChildWindow:window_ ordered:NSWindowAbove]; |
| 349 } | 348 } |
| 350 | 349 |
| 350 void StatusBubbleMac::Detach() { |
| 351 // This method may be called several times in the process of hiding or |
| 352 // destroying a status bubble. |
| 353 if (is_attached()) |
| 354 [parent_ removeChildWindow:window_]; |
| 355 } |
| 356 |
| 351 void StatusBubbleMac::AnimationDidStop(CAAnimation* animation, bool finished) { | 357 void StatusBubbleMac::AnimationDidStop(CAAnimation* animation, bool finished) { |
| 352 DCHECK([NSThread isMainThread]); | 358 DCHECK([NSThread isMainThread]); |
| 353 DCHECK(state_ == kBubbleShowingFadeIn || state_ == kBubbleHidingFadeOut); | 359 DCHECK(state_ == kBubbleShowingFadeIn || state_ == kBubbleHidingFadeOut); |
| 360 DCHECK(is_attached()); |
| 354 | 361 |
| 355 if (finished) { | 362 if (finished) { |
| 356 // Because of the mechanism used to interrupt animations, this is never | 363 // Because of the mechanism used to interrupt animations, this is never |
| 357 // actually called with finished set to false. If animations ever become | 364 // actually called with finished set to false. If animations ever become |
| 358 // directly interruptible, the check will ensure that state_ remains | 365 // directly interruptible, the check will ensure that state_ remains |
| 359 // properly synchronized. | 366 // properly synchronized. |
| 360 if (state_ == kBubbleShowingFadeIn) { | 367 if (state_ == kBubbleShowingFadeIn) { |
| 361 DCHECK_EQ([[window_ animator] alphaValue], kBubbleOpacity); | 368 DCHECK_EQ([[window_ animator] alphaValue], kBubbleOpacity); |
| 362 SetState(kBubbleShown); | 369 SetState(kBubbleShown); |
| 363 } else { | 370 } else { |
| 364 DCHECK_EQ([[window_ animator] alphaValue], 0.0); | 371 DCHECK_EQ([[window_ animator] alphaValue], 0.0); |
| 365 SetState(kBubbleHidden); | 372 SetState(kBubbleHidden); |
| 366 } | 373 } |
| 367 } | 374 } |
| 368 } | 375 } |
| 369 | 376 |
| 370 void StatusBubbleMac::SetState(StatusBubbleState state) { | 377 void StatusBubbleMac::SetState(StatusBubbleState state) { |
| 378 // We must be hidden or attached, but not both. |
| 379 DCHECK((state_ == kBubbleHidden) ^ is_attached()); |
| 380 |
| 371 if (state == state_) | 381 if (state == state_) |
| 372 return; | 382 return; |
| 373 | 383 |
| 384 if (state == kBubbleHidden) |
| 385 Detach(); |
| 386 else |
| 387 Attach(); |
| 388 |
| 374 if ([delegate_ respondsToSelector:@selector(statusBubbleWillEnterState:)]) | 389 if ([delegate_ respondsToSelector:@selector(statusBubbleWillEnterState:)]) |
| 375 [delegate_ statusBubbleWillEnterState:state]; | 390 [delegate_ statusBubbleWillEnterState:state]; |
| 376 | 391 |
| 377 state_ = state; | 392 state_ = state; |
| 378 } | 393 } |
| 379 | 394 |
| 380 void StatusBubbleMac::Fade(bool show) { | 395 void StatusBubbleMac::Fade(bool show) { |
| 381 DCHECK([NSThread isMainThread]); | 396 DCHECK([NSThread isMainThread]); |
| 382 | 397 |
| 383 StatusBubbleState fade_state = kBubbleShowingFadeIn; | 398 StatusBubbleState fade_state = kBubbleShowingFadeIn; |
| 384 StatusBubbleState target_state = kBubbleShown; | 399 StatusBubbleState target_state = kBubbleShown; |
| 385 NSTimeInterval full_duration = kShowFadeInDurationSeconds; | 400 NSTimeInterval full_duration = kShowFadeInDurationSeconds; |
| 386 CGFloat opacity = kBubbleOpacity; | 401 CGFloat opacity = kBubbleOpacity; |
| 387 | 402 |
| 388 if (!show) { | 403 if (!show) { |
| 389 fade_state = kBubbleHidingFadeOut; | 404 fade_state = kBubbleHidingFadeOut; |
| 390 target_state = kBubbleHidden; | 405 target_state = kBubbleHidden; |
| 391 full_duration = kHideFadeOutDurationSeconds; | 406 full_duration = kHideFadeOutDurationSeconds; |
| 392 opacity = 0.0; | 407 opacity = 0.0; |
| 393 } | 408 } |
| 394 | 409 |
| 395 DCHECK(state_ == fade_state || state_ == target_state); | 410 DCHECK(state_ == fade_state || state_ == target_state); |
| 396 | 411 |
| 397 if (state_ == target_state) | 412 if (state_ == target_state) |
| 398 return; | 413 return; |
| 399 | 414 |
| 400 Attach(); | |
| 401 | |
| 402 if (immediate_) { | 415 if (immediate_) { |
| 403 [window_ setAlphaValue:opacity]; | 416 [window_ setAlphaValue:opacity]; |
| 404 SetState(target_state); | 417 SetState(target_state); |
| 405 return; | 418 return; |
| 406 } | 419 } |
| 407 | 420 |
| 408 // If an incomplete transition has left the opacity somewhere between 0 and | 421 // If an incomplete transition has left the opacity somewhere between 0 and |
| 409 // kBubbleOpacity, the fade rate is kept constant by shortening the duration. | 422 // kBubbleOpacity, the fade rate is kept constant by shortening the duration. |
| 410 NSTimeInterval duration = | 423 NSTimeInterval duration = |
| 411 full_duration * | 424 full_duration * |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 if (state_ == kBubbleShowingTimer) { | 467 if (state_ == kBubbleShowingTimer) { |
| 455 SetState(kBubbleShowingFadeIn); | 468 SetState(kBubbleShowingFadeIn); |
| 456 Fade(true); | 469 Fade(true); |
| 457 } else { | 470 } else { |
| 458 SetState(kBubbleHidingFadeOut); | 471 SetState(kBubbleHidingFadeOut); |
| 459 Fade(false); | 472 Fade(false); |
| 460 } | 473 } |
| 461 } | 474 } |
| 462 | 475 |
| 463 void StatusBubbleMac::StartShowing() { | 476 void StatusBubbleMac::StartShowing() { |
| 464 Attach(); | 477 // Note that |SetState()| will |Attach()| or |Detach()| as required. |
| 465 | 478 |
| 466 if (state_ == kBubbleHidden) { | 479 if (state_ == kBubbleHidden) { |
| 467 // Arrange to begin fading in after a delay. | 480 // Arrange to begin fading in after a delay. |
| 468 SetState(kBubbleShowingTimer); | 481 SetState(kBubbleShowingTimer); |
| 469 StartTimer(kShowDelayMilliseconds); | 482 StartTimer(kShowDelayMilliseconds); |
| 470 } else if (state_ == kBubbleHidingFadeOut) { | 483 } else if (state_ == kBubbleHidingFadeOut) { |
| 471 // Cancel the fade-out in progress and replace it with a fade in. | 484 // Cancel the fade-out in progress and replace it with a fade in. |
| 472 SetState(kBubbleShowingFadeIn); | 485 SetState(kBubbleShowingFadeIn); |
| 473 Fade(true); | 486 Fade(true); |
| 474 } else if (state_ == kBubbleHidingTimer) { | 487 } else if (state_ == kBubbleHidingTimer) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 } | 532 } |
| 520 | 533 |
| 521 NSRect StatusBubbleMac::CalculateWindowFrame() { | 534 NSRect StatusBubbleMac::CalculateWindowFrame() { |
| 522 DCHECK(parent_); | 535 DCHECK(parent_); |
| 523 | 536 |
| 524 NSRect rect = [parent_ frame]; | 537 NSRect rect = [parent_ frame]; |
| 525 rect.size.height = kWindowHeight; | 538 rect.size.height = kWindowHeight; |
| 526 rect.size.width = static_cast<int>(kWindowWidthPercent * rect.size.width); | 539 rect.size.width = static_cast<int>(kWindowWidthPercent * rect.size.width); |
| 527 return rect; | 540 return rect; |
| 528 } | 541 } |
| OLD | NEW |