//////////////////////////////////////////////////////////////////////////////// // // 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.
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.
If you define a custom filter function, you can examine the
* filterProperties
property from within your function.
If you define a custom filter function, you can examine the
* filterStyles
property from within your function.
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
.
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;
}
}
}