Commit 63ad62e5 authored by groby@chromium.org's avatar groby@chromium.org

[rAC, OSX] Add overlay shield for interstitials/waits.

requestAutocomplete displays a splash screen as well as an
interstitial while communicating with wallet using the overlay shield.

The current dialog is hidden behind the shield for the duration, and
the shield can contain images as well as text messages.

R=sail@chromium.org
BUG=157274, 260951

Review URL: https://chromiumcodereview.appspot.com/23674004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221399 0039d316-1c4b-4281-b951-d872f2087c98
parent daca4a69
...@@ -25,8 +25,9 @@ namespace autofill { ...@@ -25,8 +25,9 @@ namespace autofill {
@class AutofillAccountChooser; @class AutofillAccountChooser;
@class AutofillDialogWindowController; @class AutofillDialogWindowController;
@class AutofillSignInContainer;
@class AutofillMainContainer; @class AutofillMainContainer;
@class AutofillOverlayController;
@class AutofillSignInContainer;
namespace autofill { namespace autofill {
...@@ -110,6 +111,7 @@ class AutofillDialogCocoa : public AutofillDialogView, ...@@ -110,6 +111,7 @@ class AutofillDialogCocoa : public AutofillDialogView,
base::scoped_nsobject<AutofillMainContainer> mainContainer_; base::scoped_nsobject<AutofillMainContainer> mainContainer_;
base::scoped_nsobject<AutofillSignInContainer> signInContainer_; base::scoped_nsobject<AutofillSignInContainer> signInContainer_;
base::scoped_nsobject<AutofillAccountChooser> accountChooser_; base::scoped_nsobject<AutofillAccountChooser> accountChooser_;
base::scoped_nsobject<AutofillOverlayController> overlayController_;
base::scoped_nsobject<NSTextField> loadingShieldTextField_; base::scoped_nsobject<NSTextField> loadingShieldTextField_;
} }
...@@ -128,9 +130,11 @@ class AutofillDialogCocoa : public AutofillDialogView, ...@@ -128,9 +130,11 @@ class AutofillDialogCocoa : public AutofillDialogView,
- (IBAction)cancel:(id)sender; - (IBAction)cancel:(id)sender;
// Forwarding AutofillDialogView calls. // Forwarding AutofillDialogView calls.
- (void)show;
- (void)hide; - (void)hide;
- (void)updateNotificationArea; - (void)updateNotificationArea;
- (void)updateAccountChooser; - (void)updateAccountChooser;
- (void)updateButtonStrip;
- (void)updateSection:(autofill::DialogSection)section; - (void)updateSection:(autofill::DialogSection)section;
- (void)fillSection:(autofill::DialogSection)section - (void)fillSection:(autofill::DialogSection)section
forInput:(const autofill::DetailInput&)input; forInput:(const autofill::DetailInput&)input;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#import "chrome/browser/ui/cocoa/autofill/autofill_details_container.h" #import "chrome/browser/ui/cocoa/autofill/autofill_details_container.h"
#include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h" #include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h"
#import "chrome/browser/ui/cocoa/autofill/autofill_main_container.h" #import "chrome/browser/ui/cocoa/autofill/autofill_main_container.h"
#import "chrome/browser/ui/cocoa/autofill/autofill_overlay_controller.h"
#import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h" #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h"
#import "chrome/browser/ui/cocoa/autofill/autofill_sign_in_container.h" #import "chrome/browser/ui/cocoa/autofill/autofill_sign_in_container.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h" #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h"
...@@ -63,6 +64,7 @@ void AutofillDialogCocoa::Show() { ...@@ -63,6 +64,7 @@ void AutofillDialogCocoa::Show() {
initWithCustomWindow:[sheet_delegate_ window]]); initWithCustomWindow:[sheet_delegate_ window]]);
constrained_window_.reset( constrained_window_.reset(
new ConstrainedWindowMac(this, delegate_->GetWebContents(), sheet)); new ConstrainedWindowMac(this, delegate_->GetWebContents(), sheet));
[sheet_delegate_ show];
} }
void AutofillDialogCocoa::Hide() { void AutofillDialogCocoa::Hide() {
...@@ -95,6 +97,7 @@ void AutofillDialogCocoa::UpdateAccountChooser() { ...@@ -95,6 +97,7 @@ void AutofillDialogCocoa::UpdateAccountChooser() {
} }
void AutofillDialogCocoa::UpdateButtonStrip() { void AutofillDialogCocoa::UpdateButtonStrip() {
[sheet_delegate_ updateButtonStrip];
} }
void AutofillDialogCocoa::UpdateDetailArea() { void AutofillDialogCocoa::UpdateDetailArea() {
...@@ -285,6 +288,11 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed( ...@@ -285,6 +288,11 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed(
[loadingShieldView setHidden:YES]; [loadingShieldView setHidden:YES];
[loadingShieldView addSubview:loadingShieldTextField_]; [loadingShieldView addSubview:loadingShieldTextField_];
overlayController_.reset(
[[AutofillOverlayController alloc] initWithDelegate:
autofillDialog->delegate()]);
[[overlayController_ view] setHidden:YES];
// This needs a flipped content view because otherwise the size // This needs a flipped content view because otherwise the size
// animation looks odd. However, replacing the contentView for constrained // animation looks odd. However, replacing the contentView for constrained
// windows does not work - it does custom rendering. // windows does not work - it does custom rendering.
...@@ -294,7 +302,8 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed( ...@@ -294,7 +302,8 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed(
@[accountChooser_, @[accountChooser_,
[mainContainer_ view], [mainContainer_ view],
[signInContainer_ view], [signInContainer_ view],
loadingShieldView]]; loadingShieldView,
[overlayController_ view]]];
[flippedContentView setAutoresizingMask: [flippedContentView setAutoresizingMask:
(NSViewWidthSizable | NSViewHeightSizable)]; (NSViewWidthSizable | NSViewHeightSizable)];
[[[self window] contentView] addSubview:flippedContentView]; [[[self window] contentView] addSubview:flippedContentView];
...@@ -306,17 +315,6 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed( ...@@ -306,17 +315,6 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed(
contentRect.size.height += NSHeight(headerRect) + contentRect.size.height += NSHeight(headerRect) +
chrome_style::kClientBottomPadding + chrome_style::kClientBottomPadding +
chrome_style::kTitleTopPadding; chrome_style::kTitleTopPadding;
[self performLayout];
// Resizing the browser causes the ConstrainedWindow to move.
// Observe that to allow resizes based on browser size.
NSView* contentView = [[self window] contentView];
[contentView setPostsFrameChangedNotifications:YES];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onContentViewFrameDidChange:)
name:NSWindowDidMoveNotification
object:[self window]];
} }
return self; return self;
} }
...@@ -358,6 +356,16 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed( ...@@ -358,6 +356,16 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed(
dialogFrameRect = [[self window] contentRectForFrameRect:dialogFrameRect]; dialogFrameRect = [[self window] contentRectForFrameRect:dialogFrameRect];
size.height = std::min(NSHeight(dialogFrameRect), size.height); size.height = std::min(NSHeight(dialogFrameRect), size.height);
if (![[overlayController_ view] isHidden]) {
CGFloat height = [overlayController_ heightForWidth:size.width];
// TODO(groby): This currently reserves size on top of the overlay image
// equivalent to the height of the header. Clarify with UX what the final
// padding will be.
if (height != 0.0) {
size.height = height + headerSize.height + kDetailTopPadding;
}
}
return size; return size;
} }
...@@ -393,6 +401,9 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed( ...@@ -393,6 +401,9 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed(
[loadingShieldTextField_ setFrame:textFrame]; [loadingShieldTextField_ setFrame:textFrame];
[[loadingShieldTextField_ superview] setFrame:contentRect]; [[loadingShieldTextField_ superview] setFrame:contentRect];
[[overlayController_ view] setFrame:contentRect];
[overlayController_ performLayout];
NSRect frameRect = [[self window] frameRectForContentRect:contentRect]; NSRect frameRect = [[self window] frameRectForContentRect:contentRect];
[[self window] setFrame:frameRect display:YES]; [[self window] setFrame:frameRect display:YES];
} }
...@@ -407,6 +418,29 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed( ...@@ -407,6 +418,29 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed(
autofillDialog_->PerformClose(); autofillDialog_->PerformClose();
} }
- (void)show {
gfx::Image splashImage = autofillDialog_->delegate()->SplashPageImage();
if (!splashImage.IsEmpty()) {
autofill::DialogOverlayState state;
state.image = splashImage;
[overlayController_ setState:state];
[overlayController_ beginFadeOut];
}
// Resizing the browser causes the ConstrainedWindow to move.
// Observe that to allow resizes based on browser size.
// NOTE: This MUST come last after all initial setup is done, because there
// is an immediate notification post registration.
DCHECK([self window]);
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onContentViewFrameDidChange:)
name:NSWindowDidMoveNotification
object:[self window]];
[self requestRelayout];
}
- (void)hide { - (void)hide {
autofillDialog_->delegate()->OnCancel(); autofillDialog_->delegate()->OnCancel();
autofillDialog_->PerformClose(); autofillDialog_->PerformClose();
...@@ -434,6 +468,10 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed( ...@@ -434,6 +468,10 @@ void AutofillDialogCocoa::OnConstrainedWindowClosed(
} }
} }
- (void)updateButtonStrip {
[overlayController_ updateState];
}
- (void)updateSection:(autofill::DialogSection)section { - (void)updateSection:(autofill::DialogSection)section {
[[mainContainer_ sectionForId:section] update]; [[mainContainer_ sectionForId:section] update];
} }
......
// Copyright 2013 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_UI_COCOA_AUTOFILL_AUTOFILL_OVERLAY_CONTROLLER_H_
#define CHROME_BROWSER_UI_COCOA_AUTOFILL_AUTOFILL_OVERLAY_CONTROLLER_H_
#import <Cocoa/Cocoa.h>
#include "base/mac/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
#import "chrome/browser/ui/cocoa/autofill/autofill_layout.h"
namespace autofill {
class AutofillDialogViewDelegate;
struct DialogOverlayState;
} // autofill
namespace ui {
class Animation;
class MultiAnimation;
} // ui
class AnimationDelegateBridge;
class OverlayTimerBridge;
@class AutofillMessageStackView;
// Protocol that allows Cocoa objects to act as a delegate for a ui::Animation.
@protocol AnimationDelegate
- (void)animationProgressed:(const ui::Animation*)animation;
- (void)animationEnded:(const ui::Animation*)animation;
@end
@interface AutofillOverlayController :
NSViewController<AnimationDelegate, AutofillLayout> {
@private
// |childView_| contains all overlay UI elements. This is used to fade out
// UI elements first, before making the main view transparent to fade out the
// overlay shield.
base::scoped_nsobject<NSView> childView_;
base::scoped_nsobject<NSImageView> imageView_;
base::scoped_nsobject<AutofillMessageStackView> messageStackView_;
scoped_ptr<ui::MultiAnimation> fadeOutAnimation_; // Animation rules.
scoped_ptr<AnimationDelegateBridge> animationDelegate_;
// Timer to control refresh rate of the overlay's state.
scoped_ptr<OverlayTimerBridge> refreshTimer_;
autofill::AutofillDialogViewDelegate* delegate_; // not owned, owns dialog.
}
// Designated initializer.
- (id)initWithDelegate:(autofill::AutofillDialogViewDelegate*)delegate;
// Updates the state from the dialog controller.
- (void)updateState;
// Sets a specific state for the overlay.
- (void)setState:(const autofill::DialogOverlayState&)state;
// Start the animation sequence. At its end, the dialog will hide itself.
- (void)beginFadeOut;
// Get the preferred view height for a given width.
- (CGFloat)heightForWidth:(int)width;
@end
#endif // CHROME_BROWSER_UI_COCOA_AUTOFILL_AUTOFILL_OVERLAY_CONTROLLER_H_
// Copyright 2013 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/ui/cocoa/autofill/autofill_overlay_controller.h"
#include "base/logging.h"
#include "base/mac/foundation_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/autofill/autofill_dialog_types.h"
#include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h"
#include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h"
#include "skia/ext/skia_utils_mac.h"
#include "ui/base/animation/animation_delegate.h"
#include "ui/base/animation/multi_animation.h"
namespace {
// Spacing between lines of text in the overlay view.
const CGFloat kOverlayTextInterlineSpacing = 10;
// Spacing below image and above text messages in overlay view.
const CGFloat kOverlayImageBottomMargin = 50;
// TODO(groby): Unify colors with Views.
// Slight shading for mouse hover and legal document background.
SkColor kShadingColor = 0xfff2f2f2;
// A border color for the legal document view.
SkColor kSubtleBorderColor = 0xffdfdfdf;
// Shorten a few long types.
typedef ui::MultiAnimation::Part Part;
typedef ui::MultiAnimation::Parts Parts;
} // namespace
// Bridges Objective C and C++ delegate interfaces.
class AnimationDelegateBridge : public ui::AnimationDelegate {
public:
AnimationDelegateBridge(id<AnimationDelegate> delegate);
protected:
// AnimationDelegate implementation.
virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE;
private:
id<AnimationDelegate> delegate_; // Not owned. Owns DelegateBridge.
DISALLOW_COPY_AND_ASSIGN(AnimationDelegateBridge);
};
AnimationDelegateBridge::AnimationDelegateBridge(
id<AnimationDelegate> delegate) : delegate_(delegate) {}
void AnimationDelegateBridge::AnimationProgressed(
const ui::Animation* animation) {
[delegate_ animationProgressed:animation];
}
void AnimationDelegateBridge::AnimationEnded(
const ui::Animation* animation) {
[delegate_ animationEnded:animation];
}
class OverlayTimerBridge {
public:
OverlayTimerBridge(AutofillOverlayController* controller);
void SetExpiry(const base::TimeDelta& delta);
private:
void UpdateOverlayState();
// Controls when the overlay should request a status update.
base::OneShotTimer<OverlayTimerBridge> refresh_timer_;
// not owned, |overlay_view_controller_| owns |this|.
AutofillOverlayController* overlay_view_controller_;
DISALLOW_COPY_AND_ASSIGN(OverlayTimerBridge);
};
OverlayTimerBridge::OverlayTimerBridge(AutofillOverlayController* controller)
: overlay_view_controller_(controller) {
}
void OverlayTimerBridge::SetExpiry(const base::TimeDelta& expiry) {
if (expiry != base::TimeDelta()) {
refresh_timer_.Start(FROM_HERE,
expiry,
this,
&OverlayTimerBridge::UpdateOverlayState);
} else {
refresh_timer_.Stop();
}
}
void OverlayTimerBridge::UpdateOverlayState() {
[overlay_view_controller_ updateState];
}
// An NSView encapsulating the message stack and its custom drawn elements.
@interface AutofillMessageStackView : NSView<AutofillLayout>
- (CGFloat)heightForWidth:(CGFloat)width;
- (void)setMessages:
(const std::vector<autofill::DialogOverlayString>&)messages;
@end
@implementation AutofillMessageStackView
- (void)drawRect:(NSRect)dirtyRect {
NSColor* shadingColor = gfx::SkColorToCalibratedNSColor(kShadingColor);
NSColor* borderColor = gfx::SkColorToCalibratedNSColor(kSubtleBorderColor);
CGFloat arrowHalfWidth = kArrowWidth / 2.0;
NSRect bounds = [self bounds];
CGFloat y = NSMaxY(bounds) - kArrowHeight;
NSBezierPath* arrow = [NSBezierPath bezierPath];
// Note that we purposely draw slightly outside of |bounds| so that the
// stroke is hidden on the sides and bottom.
NSRect arrowBounds = NSInsetRect(bounds, -1, -1);
arrowBounds.size.height--;
[arrow moveToPoint:NSMakePoint(NSMinX(arrowBounds), y)];
[arrow lineToPoint:
NSMakePoint(NSMidX(arrowBounds) - arrowHalfWidth, y)];
[arrow relativeLineToPoint:NSMakePoint(arrowHalfWidth, kArrowHeight)];
[arrow relativeLineToPoint:NSMakePoint(arrowHalfWidth, -kArrowHeight)];
[arrow lineToPoint:NSMakePoint(NSMaxX(arrowBounds), y)];
[arrow lineToPoint:NSMakePoint(NSMaxX(arrowBounds), NSMinY(arrowBounds))];
[arrow lineToPoint:NSMakePoint(NSMinX(arrowBounds), NSMinY(arrowBounds))];
[arrow closePath];
[shadingColor setFill];
[arrow fill];
[borderColor setStroke];
[arrow stroke];
}
- (CGFloat)heightForWidth:(CGFloat)width {
CGFloat height = kOverlayTextInterlineSpacing;
for (NSTextView* label in [self subviews]) {
height += NSHeight([label frame]);
height += kOverlayTextInterlineSpacing;
}
return height + kArrowHeight;
}
- (void)setMessages:
(const std::vector<autofill::DialogOverlayString>&) messages {
// We probably want to look at other multi-line messages somewhere.
base::scoped_nsobject<NSMutableArray> labels(
[[NSMutableArray alloc] initWithCapacity:messages.size()]);
for (size_t i = 0; i < messages.size(); ++i) {
base::scoped_nsobject<NSTextField> label(
[[NSTextField alloc] initWithFrame:NSZeroRect]);
NSFont* labelFont = messages[i].font.GetNativeFont();
[label setEditable:NO];
[label setBordered:NO];
[label setDrawsBackground:NO];
[label setFont:labelFont];
[label setStringValue:base::SysUTF16ToNSString(messages[i].text)];
[label setTextColor:gfx::SkColorToDeviceNSColor(messages[i].text_color)];
DCHECK_EQ(messages[i].alignment, gfx::ALIGN_CENTER);
[label setAlignment:NSCenterTextAlignment];
[label sizeToFit];
[labels addObject:label];
}
[self setSubviews:labels];
[self setHidden:([labels count] == 0)];
}
- (void)performLayout {
CGFloat y =
NSMaxY([self bounds]) - kArrowHeight - kOverlayTextInterlineSpacing;
for (NSTextView* label in [self subviews]) {
DCHECK([label isKindOfClass:[NSTextView class]]);
CGFloat labelHeight = NSHeight([label frame]);
[label setFrame:NSMakeRect(0, y - labelHeight,
NSWidth([self bounds]), labelHeight)];
y = NSMinY([label frame]) - kOverlayTextInterlineSpacing;
}
DCHECK_GT(0.0, y);
}
- (NSSize)preferredSize {
NOTREACHED();
return NSZeroSize;
}
@end
@implementation AutofillOverlayController
- (id)initWithDelegate:(autofill::AutofillDialogViewDelegate*)delegate {
if (self = [super initWithNibName:nil bundle:nil]) {
delegate_ = delegate;
refreshTimer_.reset(new OverlayTimerBridge(self));
base::scoped_nsobject<NSBox> view(
[[NSBox alloc] initWithFrame:NSZeroRect]);
[view setBoxType:NSBoxCustom];
[view setBorderType:NSNoBorder];
[view setContentViewMargins:NSZeroSize];
[view setTitlePosition:NSNoTitle];
childView_.reset([[NSView alloc] initWithFrame:NSZeroRect]);
messageStackView_.reset(
[[AutofillMessageStackView alloc] initWithFrame:NSZeroRect]);
imageView_.reset([[NSImageView alloc] initWithFrame:NSZeroRect]);
[imageView_ setImageAlignment:NSImageAlignCenter];
[childView_ setSubviews:@[messageStackView_, imageView_]];
[view addSubview:childView_];
[self setView:view];
}
return self;
}
- (void)updateState {
[self setState:delegate_->GetDialogOverlay()];
}
- (void)setState:(const autofill::DialogOverlayState&)state {
// Don't update anything if we're still fading out the old state.
if (fadeOutAnimation_)
return;
if (state.image.IsEmpty()) {
[[self view] setHidden:YES];
return;
}
NSBox* view = base::mac::ObjCCastStrict<NSBox>([self view]);
[view setFillColor:[[view window] backgroundColor]];
[view setAlphaValue:1];
[childView_ setAlphaValue:1];
[imageView_ setImage:state.image.ToNSImage()];
[messageStackView_ setMessages:state.strings];
[childView_ setHidden:NO];
[view setHidden:NO];
NSWindowController* delegate = [[[self view] window] windowController];
if ([delegate respondsToSelector:@selector(requestRelayout)])
[delegate performSelector:@selector(requestRelayout)];
refreshTimer_->SetExpiry(state.expiry);
}
- (void)beginFadeOut {
// Remove first responders, since focus rings show on top of overlay view.
// TODO(groby): Figure out to do that less hacky. Ideally, the focus ring
// should be part of the controls fading in, not appear at the end.
[[self view] setNextResponder:[[[self view] window] firstResponder]];
[[[self view] window] makeFirstResponder:[self view]];
Parts parts;
// For this part of the animation, simply show the splash image.
parts.push_back(Part(autofill::kSplashDisplayDurationMs, ui::Tween::ZERO));
// For this part of the animation, fade out the splash image.
parts.push_back(
Part(autofill::kSplashFadeOutDurationMs, ui::Tween::EASE_IN));
// For this part of the animation, fade out |this| (fade in the dialog).
parts.push_back(
Part(autofill::kSplashFadeInDialogDurationMs, ui::Tween::EASE_OUT));
fadeOutAnimation_.reset(
new ui::MultiAnimation(parts,
ui::MultiAnimation::GetDefaultTimerInterval()));
animationDelegate_.reset(new AnimationDelegateBridge(self));
fadeOutAnimation_->set_delegate(animationDelegate_.get());
fadeOutAnimation_->set_continuous(false);
fadeOutAnimation_->Start();
}
- (CGFloat)heightForWidth:(int) width {
// 0 means "no preference". Image-only overlays fit the container.
if ([messageStackView_ isHidden])
return 0;
// Overlays with text messages express a size preference.
return kOverlayImageBottomMargin +
[messageStackView_ heightForWidth:width] +
NSHeight([imageView_ frame]);
}
- (NSSize)preferredSize {
NOTREACHED(); // Only implemented as part of AutofillLayout protocol.
return NSZeroSize;
}
- (void)performLayout {
NSRect bounds = [[self view] bounds];
[childView_ setFrame:bounds];
if ([messageStackView_ isHidden]) {
[imageView_ setFrame:bounds];
return;
}
int messageHeight = [messageStackView_ heightForWidth:NSWidth(bounds)];
[messageStackView_ setFrame:
NSMakeRect(0, 0, NSWidth(bounds), messageHeight)];
[messageStackView_ performLayout];
NSSize imageSize = [[imageView_ image] size];
[imageView_ setFrame:NSMakeRect(
0, NSMaxY([messageStackView_ frame]) + kOverlayImageBottomMargin,
NSWidth(bounds), imageSize.height)];
}
- (void)animationProgressed:(const ui::Animation*)animation {
DCHECK_EQ(animation, fadeOutAnimation_.get());
// Fade out children in stage 1.
if (fadeOutAnimation_->current_part_index() == 1) {
[childView_ setAlphaValue:(1 - fadeOutAnimation_->GetCurrentValue())];
}
// Fade out background in stage 2(i.e. fade in what's behind |this|).
if (fadeOutAnimation_->current_part_index() == 2) {
[[self view] setAlphaValue: (1 - fadeOutAnimation_->GetCurrentValue())];
[childView_ setHidden:YES];
}
// If any fading was done, refresh display.
if (fadeOutAnimation_->current_part_index() != 0) {
[[self view] setNeedsDisplay:YES];
}
}
- (void)animationEnded:(const ui::Animation*)animation {
DCHECK_EQ(animation, fadeOutAnimation_.get());
[[self view] setHidden:YES];
fadeOutAnimation_.reset();
}
@end
\ No newline at end of file
// Copyright 2013 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/ui/cocoa/autofill/autofill_overlay_controller.h"
#include "base/mac/scoped_nsobject.h"
#include "chrome/browser/ui/autofill/mock_autofill_dialog_view_delegate.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"
#import "ui/base/test/ui_cocoa_test_helper.h"
namespace {
class AutofillOverlayControllerTest : public ui::CocoaTest {
public:
virtual void SetUp() {
CocoaTest::SetUp();
controller_.reset(
[[AutofillOverlayController alloc] initWithDelegate:&delegate_]);
[[test_window() contentView] addSubview:[controller_ view]];
}
protected:
base::scoped_nsobject<AutofillOverlayController> controller_;
testing::NiceMock<autofill::MockAutofillDialogViewDelegate> delegate_;
};
} // namespace
TEST_VIEW(AutofillOverlayControllerTest, [controller_ view])
TEST_F(AutofillOverlayControllerTest, Subviews) {
NSView* view = [controller_ view];
ASSERT_EQ(1U, [[view subviews] count]);
EXPECT_TRUE([view isKindOfClass:[NSBox class]]);
EXPECT_TRUE([[[view subviews] objectAtIndex:0] isMemberOfClass:
[NSView class]]);
}
...@@ -456,6 +456,8 @@ ...@@ -456,6 +456,8 @@
'browser/ui/cocoa/autofill/autofill_notification_controller.mm', 'browser/ui/cocoa/autofill/autofill_notification_controller.mm',
'browser/ui/cocoa/autofill/autofill_main_container.h', 'browser/ui/cocoa/autofill/autofill_main_container.h',
'browser/ui/cocoa/autofill/autofill_main_container.mm', 'browser/ui/cocoa/autofill/autofill_main_container.mm',
'browser/ui/cocoa/autofill/autofill_overlay_controller.h',
'browser/ui/cocoa/autofill/autofill_overlay_controller.mm',
'browser/ui/cocoa/autofill/autofill_popup_view_bridge.h', 'browser/ui/cocoa/autofill/autofill_popup_view_bridge.h',
'browser/ui/cocoa/autofill/autofill_popup_view_bridge.mm', 'browser/ui/cocoa/autofill/autofill_popup_view_bridge.mm',
'browser/ui/cocoa/autofill/autofill_popup_view_cocoa.h', 'browser/ui/cocoa/autofill/autofill_popup_view_cocoa.h',
......
...@@ -1408,6 +1408,7 @@ ...@@ -1408,6 +1408,7 @@
'browser/ui/cocoa/autofill/autofill_main_container_unittest.mm', 'browser/ui/cocoa/autofill/autofill_main_container_unittest.mm',
'browser/ui/cocoa/autofill/autofill_notification_container_unittest.mm', 'browser/ui/cocoa/autofill/autofill_notification_container_unittest.mm',
'browser/ui/cocoa/autofill/autofill_notification_controller_unittest.mm', 'browser/ui/cocoa/autofill/autofill_notification_controller_unittest.mm',
'browser/ui/cocoa/autofill/autofill_overlay_controller_unittest.mm',
'browser/ui/cocoa/autofill/autofill_pop_up_button_unittest.mm', 'browser/ui/cocoa/autofill/autofill_pop_up_button_unittest.mm',
'browser/ui/cocoa/autofill/autofill_textfield_unittest.mm', 'browser/ui/cocoa/autofill/autofill_textfield_unittest.mm',
'browser/ui/cocoa/autofill/autofill_section_container_unittest.mm', 'browser/ui/cocoa/autofill/autofill_section_container_unittest.mm',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment