// 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) {} virtual ~MediaIndicatorViewAnimationDelegate() {} void SetAnimationDoneCallback(id anObject, SEL selector) { doneCallbackObject_ = anObject; doneCallbackSelector_ = selector; } virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE { *animatingMediaState_ = *mediaState_; [view_ setNeedsDisplay:YES]; [doneCallbackObject_ performSelector:doneCallbackSelector_]; } virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE { [view_ setNeedsDisplay:YES]; } virtual 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