/*****************************************************
*
* Copyright 2009 Adobe Systems Incorporated. All Rights Reserved.
*
*****************************************************
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
*
* The Initial Developer of the Original Code is Adobe Systems Incorporated.
* Portions created by Adobe Systems Incorporated are Copyright (C) 2009 Adobe Systems
* Incorporated. All Rights Reserved.
*
*****************************************************/
package org.osmf.elements.compositeClasses
{
import org.osmf.events.AudioEvent;
import org.osmf.traits.AudioTrait;
import org.osmf.traits.MediaTraitBase;
import org.osmf.traits.MediaTraitType;
/**
* Implementation of AudioTrait which can be a composite media trait.
*
* For both parallel and serial media elements, a composite audio trait
* keeps all audio properties in sync for the composite element and its
* children.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
internal class CompositeAudioTrait extends AudioTrait implements IReusable
{
/**
* Constructor.
*
* @param traitAggregator The object which is aggregating all instances
* of the AudioTrait within this composite trait.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion OSMF 1.0
*/
public function CompositeAudioTrait(traitAggregator:TraitAggregator)
{
super();
this.traitAggregator = traitAggregator;
traitAggregationHelper = new TraitAggregationHelper
( traitType
, traitAggregator
, processAggregatedChild
, processUnaggregatedChild
);
}
/**
* @private
*/
public function attach():void
{
traitAggregationHelper.attach();
}
/**
* @private
*/
public function detach():void
{
traitAggregationHelper.detach();
}
// Overrides
//
override protected function volumeChangeStart(newVolume:Number):void
{
applyVolumeToChildren(newVolume);
}
override protected function mutedChangeStart(newMuted:Boolean):void
{
applyMutedToChildren(newMuted);
}
override protected function panChangeStart(newPan:Number):void
{
applyPanToChildren(newPan);
}
// Internals
//
private function processAggregatedChild(child:MediaTraitBase):void
{
child.addEventListener(AudioEvent.MUTED_CHANGE, onMutedChanged, false, 0, true);
child.addEventListener(AudioEvent.PAN_CHANGE, onPanChanged, false, 0, true);
child.addEventListener(AudioEvent.VOLUME_CHANGE, onVolumeChanged, false, 0, true);
var audioTrait:AudioTrait = child as AudioTrait;
if (traitAggregator.getNumTraits(MediaTraitType.AUDIO) == 1)
{
// The first added child's properties are applied to the
// composite trait.
pan = audioTrait.pan;
muted = audioTrait.muted;
volume = audioTrait.volume;
}
else
{
// All subsequently added children inherit their properties
// from the composite trait.
audioTrait.pan = pan;
audioTrait.muted = muted;
audioTrait.volume = volume;
}
}
private function processUnaggregatedChild(child:MediaTraitBase):void
{
// All we need to do is remove the listeners. For both parallel
// and serial media, unaggregated children have no bearing on
// the properties of the composite trait.
child.removeEventListener(AudioEvent.MUTED_CHANGE, onMutedChanged);
child.removeEventListener(AudioEvent.PAN_CHANGE, onPanChanged);
child.removeEventListener(AudioEvent.VOLUME_CHANGE, onVolumeChanged);
}
private function onVolumeChanged(event:AudioEvent):void
{
// Changes from the child propagate to the composite trait.
volume = (event.target as AudioTrait).volume;
}
private function onMutedChanged(event:AudioEvent):void
{
// Changes from the child propagate to the composite trait.
muted = (event.target as AudioTrait).muted;
}
private function onPanChanged(event:AudioEvent):void
{
/// Changes from the child propagate to the composite trait.
pan = (event.target as AudioTrait).pan;
}
private function applyVolumeToChildren(newVolume:Number):void
{
traitAggregator.forEachChildTrait
(
function(mediaTrait:MediaTraitBase):void
{
AudioTrait(mediaTrait).volume = newVolume;
}
, MediaTraitType.AUDIO
);
}
private function applyMutedToChildren(newMuted:Boolean):void
{
traitAggregator.forEachChildTrait
(
function(mediaTrait:MediaTraitBase):void
{
AudioTrait(mediaTrait).muted = newMuted;
}
, MediaTraitType.AUDIO
);
}
private function applyPanToChildren(newPan:Number):void
{
traitAggregator.forEachChildTrait
(
function(mediaTrait:MediaTraitBase):void
{
AudioTrait(mediaTrait).pan = newPan;
}
, MediaTraitType.AUDIO
);
}
private var traitAggregator:TraitAggregator;
private var traitAggregationHelper:TraitAggregationHelper;
}
}