1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import "chrome/browser/ui/cocoa/tabs/media_indicator_view.h"
7 #include "ui/gfx/animation/animation.h"
8 #include "ui/gfx/animation/animation_delegate.h"
9 #include "ui/gfx/image/image.h"
11 class MediaIndicatorViewAnimationDelegate : public gfx::AnimationDelegate {
13 MediaIndicatorViewAnimationDelegate(NSView* view,
14 TabMediaState* mediaState,
15 TabMediaState* animatingMediaState)
16 : view_(view), mediaState_(mediaState),
17 animatingMediaState_(animatingMediaState),
18 doneCallbackObject_(nil), doneCallbackSelector_(nil) {}
19 virtual ~MediaIndicatorViewAnimationDelegate() {}
21 void SetAnimationDoneCallback(id anObject, SEL selector) {
22 doneCallbackObject_ = anObject;
23 doneCallbackSelector_ = selector;
26 virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE {
27 *animatingMediaState_ = *mediaState_;
28 [view_ setNeedsDisplay:YES];
29 [doneCallbackObject_ performSelector:doneCallbackSelector_];
31 virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE {
32 [view_ setNeedsDisplay:YES];
34 virtual void AnimationCanceled(const gfx::Animation* animation) OVERRIDE {
35 AnimationEnded(animation);
40 TabMediaState* const mediaState_;
41 TabMediaState* const animatingMediaState_;
43 id doneCallbackObject_;
44 SEL doneCallbackSelector_;
47 @implementation MediaIndicatorView
49 @synthesize mediaState = mediaState_;
50 @synthesize animatingMediaState = animatingMediaState_;
53 if ((self = [super initWithFrame:NSZeroRect])) {
54 mediaState_ = animatingMediaState_ = TAB_MEDIA_STATE_NONE;
55 delegate_.reset(new MediaIndicatorViewAnimationDelegate(
56 self, &mediaState_, &animatingMediaState_));
61 - (void)updateIndicator:(TabMediaState)mediaState {
62 if (mediaState == mediaState_)
65 mediaState_ = mediaState;
68 // Prepare this view if the new TabMediaState is an active one.
69 if (mediaState_ != TAB_MEDIA_STATE_NONE) {
70 animatingMediaState_ = mediaState_;
71 NSImage* const image =
72 chrome::GetTabMediaIndicatorImage(mediaState_).ToNSImage();
73 NSRect frame = [self frame];
74 frame.size = [image size];
75 [self setFrame:frame];
76 [self setImage:image];
79 // If the animation delegate is missing, that means animations were disabled
80 // for testing; so, go directly to animating completion state.
82 animatingMediaState_ = mediaState_;
86 animation_ = chrome::CreateTabMediaIndicatorFadeAnimation(mediaState_);
87 animation_->set_delegate(delegate_.get());
91 - (void)setAnimationDoneCallbackObject:(id)anObject withSelector:(SEL)selector {
93 delegate_->SetAnimationDoneCallback(anObject, selector);
96 - (void)drawRect:(NSRect)rect {
100 double opaqueness = animation_->GetCurrentValue();
101 if (mediaState_ == TAB_MEDIA_STATE_NONE)
102 opaqueness = 1.0 - opaqueness; // Fading out, not in.
104 [[self image] drawInRect:[self bounds]
106 operation:NSCompositeSourceOver
107 fraction:opaqueness];
110 - (void)disableAnimations {