blob: e3e71cdbcb1d09675e34b21602bb938ffe22a097 [file] [log] [blame]
// 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/tabs/media_indicator_view.h"
#include "ui/gfx/animation/animation.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/image/image.h"
class MediaIndicatorViewAnimationDelegate : public gfx::AnimationDelegate {
public:
MediaIndicatorViewAnimationDelegate(NSView* view,
TabMediaState* mediaState,
TabMediaState* animatingMediaState)
: view_(view), mediaState_(mediaState),
animatingMediaState_(animatingMediaState),
doneCallbackObject_(nil), doneCallbackSelector_(nil) {}
~MediaIndicatorViewAnimationDelegate() override {}
void SetAnimationDoneCallback(id anObject, SEL selector) {
doneCallbackObject_ = anObject;
doneCallbackSelector_ = selector;
}
void AnimationEnded(const gfx::Animation* animation) override {
*animatingMediaState_ = *mediaState_;
[view_ setNeedsDisplay:YES];
[doneCallbackObject_ performSelector:doneCallbackSelector_];
}
void AnimationProgressed(const gfx::Animation* animation) override {
[view_ setNeedsDisplay:YES];
}
void AnimationCanceled(const gfx::Animation* animation) override {
AnimationEnded(animation);
}
private:
NSView* const view_;
TabMediaState* const mediaState_;
TabMediaState* const animatingMediaState_;
id doneCallbackObject_;
SEL doneCallbackSelector_;
};
@implementation MediaIndicatorView
@synthesize mediaState = mediaState_;
@synthesize animatingMediaState = animatingMediaState_;
- (id)init {
if ((self = [super initWithFrame:NSZeroRect])) {
mediaState_ = animatingMediaState_ = TAB_MEDIA_STATE_NONE;
delegate_.reset(new MediaIndicatorViewAnimationDelegate(
self, &mediaState_, &animatingMediaState_));
}
return self;
}
- (void)updateIndicator:(TabMediaState)mediaState {
if (mediaState == mediaState_)
return;
mediaState_ = mediaState;
animation_.reset();
// Prepare this view if the new TabMediaState is an active one.
if (mediaState_ != TAB_MEDIA_STATE_NONE) {
animatingMediaState_ = mediaState_;
NSImage* const image =
chrome::GetTabMediaIndicatorImage(mediaState_).ToNSImage();
NSRect frame = [self frame];
frame.size = [image size];
[self setFrame:frame];
[self setImage:image];
}
// If the animation delegate is missing, that means animations were disabled
// for testing; so, go directly to animating completion state.
if (!delegate_) {
animatingMediaState_ = mediaState_;
return;
}
animation_ = chrome::CreateTabMediaIndicatorFadeAnimation(mediaState_);
animation_->set_delegate(delegate_.get());
animation_->Start();
}
- (void)setAnimationDoneCallbackObject:(id)anObject withSelector:(SEL)selector {
if (delegate_)
delegate_->SetAnimationDoneCallback(anObject, selector);
}
- (void)drawRect:(NSRect)rect {
if (!animation_)
return;
double opaqueness = animation_->GetCurrentValue();
if (mediaState_ == TAB_MEDIA_STATE_NONE)
opaqueness = 1.0 - opaqueness; // Fading out, not in.
[[self image] drawInRect:[self bounds]
fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:opaqueness];
}
- (void)disableAnimations {
delegate_.reset();
}
@end