//////////////////////////////////////////////////////////////////////////////// // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (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.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// package mx.effects { import mx.effects.effectClasses.PropertyChanges; /** * The EffectTargetFilter class defines a custom filter that is executed * by each transition effect on each target of the effect. * *

The EffectTargetFilter class defines a * defaultFilterFunction() method that uses the * filterProperties and filterStyles properties * to determine whether to play the effect on each effect target.

* *

You can also define a custom filter function * to implement your own filtering logic. * To do so, define your filter function, and then specify that function * to an EffectTargetFilter object using the filterFunction * property.

* *

To configure an effect to use a custom filter, you pass an * EffectTargetFilter object to the Effect.customFilter property * of the effect.

* * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class EffectTargetFilter { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function EffectTargetFilter() { super(); } //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // filterFunction //---------------------------------- /** * A function that defines custom filter logic. * Flex calls this method on every target of the effect. * If the function returns true, * the effect plays on the target; * if it returns false, the target is skipped by the effect. * A custom filter function gives you greater control over filtering * than the Effect.filter property. * *

The filter function has the following signature:

* *
     *  filterFunc(propChanges:Array, instanceTarget:Object):Boolean
     *  {
     *      // Return true to play the effect on instanceTarget, 
     *      // or false to not play the effect.
     *  } 
     *  
* *

where:

* *

propChanges - An Array of PropertyChanges objects, * one object per target component of the effect. * If a property of a target is not modified by the transition, * it is not included in this Array.

* *

instanceTarget - The specific target component * of the effect that you want to filter. * Within the custom filter function, you first search the * propChanges Array for the PropertyChanges object * that matches the instanceTarget argument * by comparing the instanceTarget argument * to the propChanges.target property.

* * @see mx.effects.effectClasses.PropertyChanges * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var filterFunction:Function = defaultFilterFunctionEx; //---------------------------------- // filterProperties //---------------------------------- /** * An Array of Strings specifying component properties. * If any of the properties in the Array changed on the target component, * play the effect on the target. * *

If you define a custom filter function, you can examine the * filterProperties property from within your function.

* * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var filterProperties:Array = []; //---------------------------------- // filterStyles //---------------------------------- /** * An Array of Strings specifying style properties. * If any of the style properties in the Array changed on the target component, * play the effect on the target. * *

If you define a custom filter function, you can examine the * filterStyles property from within your function.

* * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var filterStyles:Array = []; //---------------------------------- // requiredSemantics //---------------------------------- /** * A collection of properties and associated values which must be associated * with a target for the effect to be played. * *

When working with data effects, you can use this property to filter effects. * If you want to play a data effect on all targets of a list control * that are not added by the effect, meaning targets that is removed, replaced, moved, * or affected in any other way, you can write the effect definition as shown below:

* *
     *  <mx:Blur>
     *      <mx:customFilter>
     *          <mx:EffectTargetFilter requiredSemantics="{{'added':false}}"/>
     *      </mx:customFilter>
     *  </mx:Blur> 
* *

To play a data effect on all targets that are not added or not removed by the effect, * you can write the effect definition as shown below:

* *
     *  <mx:Blur>
     *      <mx:customFilter>
     *          <mx:EffectTargetFilter requiredSemantics="{{'added':false}, {'removed':false}}"/>
     *      </mx:customFilter>
     *  </mx:Blur>
* *

The allowed list of properties that you can specify includes added, * removed, replaced, and replacement. * The allowed values for the properties are true and false.

* * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var requiredSemantics:Object = null; //-------------------------------------------------------------------------- // // Methods // //-------------------------------------------------------------------------- /** * Determines whether a target should be filtered, returning true if it should be * included in an effect. * * The determination is made by calling filterFunction and semanticFilterFunction, * returning true if and only if both functions return true. The default functions * with the default values will always return true. * * Typically, an EffectTargetFilter will use one type of filter or the other, but * not both. * * @param propChanges An Array of PropertyChanges objects. The target property of * each PropertyChanges object is equal to the effect's target. If a property of * a target is not modified by a transition, the corresponding PropertyChanges * object is not included in this array. * * @param semanticsProvider The IEffectTargetHost used to evaluate the properties * specified in requiredSemantics for the target, normally the effectTargetHost of * the effect. For item change effects, when the targets of the effect are item * renderers, this will be the List or TileList containing the item renderers. * * @param target The target of the EffectInstance that calls this function. If an * effect has multiple targets, this function is called once per target. * * @return Returna true, if the target should be included in the effect; * otherwise returns false. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function filterInstance(propChanges:Array, semanticsProvider:IEffectTargetHost, target:Object):Boolean { if (filterFunction.length == 2) return filterFunction(propChanges, target); else return filterFunction(propChanges, semanticsProvider, target); } /** * @private */ protected function defaultFilterFunctionEx(propChanges:Array, semanticsProvider:IEffectTargetHost, target:Object):Boolean { if (requiredSemantics) { for (var prop:String in requiredSemantics) { // seems dumb to check this every time // if necessary, we could do something with setters and getters if (!semanticsProvider) return false; if (semanticsProvider.getRendererSemanticValue(target,prop) != requiredSemantics[prop]) return false; } // not clear this is the right thing to do here // the problem is that defaultFilterFunction returns false in // some cases where we might expect it to return true return true; } // if semantic filtering has passed, do property change filtering return defaultFilterFunction(propChanges, target); } /** * The default filter function for the EffectTargetFilter class. * If the instanceTarget has different start and end values * for any of the values specified by the filterProperties * or filterStyles properties, play the effect on the target. * * @param propChanges An Array of PropertyChanges objects. * The target property of each PropertyChanges object * is equal to the effect's target. * If a property of a target is not modified by a transition, the * corresponding PropertyChanges * object is not included in this array. * * @param instanceTarget The target of the EffectInstance * that calls this function. * If an effect has multiple targets, * this function is called once per target. * * @return Returns true to allow the effect instance to play. * * @see mx.effects.effectClasses.PropertyChanges * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function defaultFilterFunction(propChanges:Array, instanceTarget:Object):Boolean { var n:int = propChanges.length; for (var i:int = 0; i < n; i++) { var props:PropertyChanges = propChanges[i]; if (props.target == instanceTarget) { var triggers:Array = filterProperties.concat(filterStyles); var m:int = triggers.length; for (var j:int = 0; j < m; j++) { if (props.start[triggers[j]] !== undefined && props.end[triggers[j]] != props.start[triggers[j]]) { return true; } } } } return false; } } }