1/***************************************************** 2* 3* Copyright 2009 Adobe Systems Incorporated. All Rights Reserved. 4* 5***************************************************** 6* The contents of this file are subject to the Mozilla Public License 7* Version 1.1 (the "License"); you may not use this file except in 8* compliance with the License. You may obtain a copy of the License at 9* http://www.mozilla.org/MPL/ 10* 11* Software distributed under the License is distributed on an "AS IS" 12* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 13* License for the specific language governing rights and limitations 14* under the License. 15* 16* 17* The Initial Developer of the Original Code is Adobe Systems Incorporated. 18* Portions created by Adobe Systems Incorporated are Copyright (C) 2009 Adobe Systems 19* Incorporated. All Rights Reserved. 20* 21*****************************************************/ 22package org.osmf.elements.compositeClasses 23{ 24 import org.osmf.events.AudioEvent; 25 import org.osmf.traits.AudioTrait; 26 import org.osmf.traits.MediaTraitBase; 27 import org.osmf.traits.MediaTraitType; 28 29 /** 30 * Implementation of AudioTrait which can be a composite media trait. 31 * 32 * For both parallel and serial media elements, a composite audio trait 33 * keeps all audio properties in sync for the composite element and its 34 * children. 35 * 36 * @langversion 3.0 37 * @playerversion Flash 10 38 * @playerversion AIR 1.5 39 * @productversion OSMF 1.0 40 */ 41 internal class CompositeAudioTrait extends AudioTrait implements IReusable 42 { 43 /** 44 * Constructor. 45 * 46 * @param traitAggregator The object which is aggregating all instances 47 * of the AudioTrait within this composite trait. 48 * 49 * @langversion 3.0 50 * @playerversion Flash 10 51 * @playerversion AIR 1.5 52 * @productversion OSMF 1.0 53 */ 54 public function CompositeAudioTrait(traitAggregator:TraitAggregator) 55 { 56 super(); 57 58 this.traitAggregator = traitAggregator; 59 traitAggregationHelper = new TraitAggregationHelper 60 ( traitType 61 , traitAggregator 62 , processAggregatedChild 63 , processUnaggregatedChild 64 ); 65 } 66 67 /** 68 * @private 69 */ 70 public function attach():void 71 { 72 traitAggregationHelper.attach(); 73 } 74 75 /** 76 * @private 77 */ 78 public function detach():void 79 { 80 traitAggregationHelper.detach(); 81 } 82 83 // Overrides 84 // 85 86 override protected function volumeChangeStart(newVolume:Number):void 87 { 88 applyVolumeToChildren(newVolume); 89 } 90 91 override protected function mutedChangeStart(newMuted:Boolean):void 92 { 93 applyMutedToChildren(newMuted); 94 } 95 96 override protected function panChangeStart(newPan:Number):void 97 { 98 applyPanToChildren(newPan); 99 } 100 101 // Internals 102 // 103 104 private function processAggregatedChild(child:MediaTraitBase):void 105 { 106 child.addEventListener(AudioEvent.MUTED_CHANGE, onMutedChanged, false, 0, true); 107 child.addEventListener(AudioEvent.PAN_CHANGE, onPanChanged, false, 0, true); 108 child.addEventListener(AudioEvent.VOLUME_CHANGE, onVolumeChanged, false, 0, true); 109 110 var audioTrait:AudioTrait = child as AudioTrait; 111 112 if (traitAggregator.getNumTraits(MediaTraitType.AUDIO) == 1) 113 { 114 // The first added child's properties are applied to the 115 // composite trait. 116 pan = audioTrait.pan; 117 muted = audioTrait.muted; 118 volume = audioTrait.volume; 119 } 120 else 121 { 122 // All subsequently added children inherit their properties 123 // from the composite trait. 124 audioTrait.pan = pan; 125 audioTrait.muted = muted; 126 audioTrait.volume = volume; 127 } 128 } 129 130 private function processUnaggregatedChild(child:MediaTraitBase):void 131 { 132 // All we need to do is remove the listeners. For both parallel 133 // and serial media, unaggregated children have no bearing on 134 // the properties of the composite trait. 135 child.removeEventListener(AudioEvent.MUTED_CHANGE, onMutedChanged); 136 child.removeEventListener(AudioEvent.PAN_CHANGE, onPanChanged); 137 child.removeEventListener(AudioEvent.VOLUME_CHANGE, onVolumeChanged); 138 } 139 140 private function onVolumeChanged(event:AudioEvent):void 141 { 142 // Changes from the child propagate to the composite trait. 143 volume = (event.target as AudioTrait).volume; 144 } 145 146 private function onMutedChanged(event:AudioEvent):void 147 { 148 // Changes from the child propagate to the composite trait. 149 muted = (event.target as AudioTrait).muted; 150 } 151 152 private function onPanChanged(event:AudioEvent):void 153 { 154 /// Changes from the child propagate to the composite trait. 155 pan = (event.target as AudioTrait).pan; 156 } 157 158 private function applyVolumeToChildren(newVolume:Number):void 159 { 160 traitAggregator.forEachChildTrait 161 ( 162 function(mediaTrait:MediaTraitBase):void 163 { 164 AudioTrait(mediaTrait).volume = newVolume; 165 } 166 , MediaTraitType.AUDIO 167 ); 168 } 169 170 private function applyMutedToChildren(newMuted:Boolean):void 171 { 172 traitAggregator.forEachChildTrait 173 ( 174 function(mediaTrait:MediaTraitBase):void 175 { 176 AudioTrait(mediaTrait).muted = newMuted; 177 } 178 , MediaTraitType.AUDIO 179 ); 180 } 181 182 private function applyPanToChildren(newPan:Number):void 183 { 184 traitAggregator.forEachChildTrait 185 ( 186 function(mediaTrait:MediaTraitBase):void 187 { 188 AudioTrait(mediaTrait).pan = newPan; 189 } 190 , MediaTraitType.AUDIO 191 ); 192 } 193 194 private var traitAggregator:TraitAggregator; 195 private var traitAggregationHelper:TraitAggregationHelper; 196 } 197}