////////////////////////////////////////////////////////////////////////////////
//
// 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.effectClasses
{
import flash.events.Event;
import mx.core.EdgeMetrics;
import mx.core.IContainer;
import mx.core.IUIComponent;
import mx.core.mx_internal;
import mx.effects.EffectManager;
import mx.events.MoveEvent;
import mx.styles.IStyleClient;
use namespace mx_internal;
/**
* The MoveInstance class implements the instance class
* for the Move effect.
* Flex creates an instance of this class when it plays a Move effect;
* you do not create one yourself.
*
*
Every effect class that is a subclass of the TweenEffect class
* supports the following events:
*
*
* tweenEnd
: Dispatched when the tween effect ends.
*
* tweenUpdate
: Dispatched every time a TweenEffect
* class calculates a new value.
*
*
* The event object passed to the event listener for these events is of type TweenEvent.
* The TweenEvent class defines the property value
, which contains
* the tween value calculated by the effect.
* For the Move effect,
* the TweenEvent.value
property contains a 2-item Array, where:
*
* - value[0]:Number A value between the values of the
Move.xFrom
* and Move.xTo
property.
*
* - value[1]:Number A value between the values of the
Move.yFrom
* and Move.yTo
property.
*
*
* @see mx.effects.Move
* @see mx.events.TweenEvent
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public class MoveInstance extends TweenEffectInstance
{
include "../../core/Version.as";
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*
* @param target The Object to animate with this effect.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function MoveInstance(target:Object)
{
super(target);
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
* Stores the left style of the target
*/
private var left:*;
/**
* @private
* Stores the right style of the target
*/
private var right:*;
/**
* @private
* Stores the top style of the target
*/
private var top:*;
/**
* @private
* Stores the bottom style of the target
*/
private var bottom:*;
/**
* @private
* Stores the horizontalCenter style of the target
*/
private var horizontalCenter:*;
/**
* @private
* Stores the verticalCenter style of the target
*/
private var verticalCenter:*;
/**
* @private
*/
private var forceClipping:Boolean = false;
/**
* @private
*/
private var checkClipping:Boolean = true;
private var oldWidth:Number;
private var oldHeight:Number;
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// xBy
//----------------------------------
/**
* Number of pixels to move the components along the x axis.
* Values can be negative.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public var xBy:Number;
//----------------------------------
// xFrom
//----------------------------------
/**
* Initial position's x coordinate.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public var xFrom:Number;
//----------------------------------
// xTo
//----------------------------------
/**
* Destination position's x coordinate.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public var xTo:Number;
//----------------------------------
// yBy
//----------------------------------
/**
* Number of pixels to move the components along the y axis.
* Values can be negative.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public var yBy:Number;
//----------------------------------
// yFrom
//----------------------------------
/**
* Initial position's y coordinate.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public var yFrom:Number;
//----------------------------------
// yTo
//----------------------------------
/**
* Destination position's y coordinate.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public var yTo:Number;
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
/**
* @private
*/
override public function initEffect(event:Event):void
{
super.initEffect(event);
if (event is MoveEvent && event.type == MoveEvent.MOVE)
{
if (isNaN(xFrom) &&
isNaN(xTo) &&
isNaN(xBy) &&
isNaN(yFrom) &&
isNaN(yTo) &&
isNaN(yBy))
{
xFrom = MoveEvent(event).oldX;
xTo = target.x;
yFrom = MoveEvent(event).oldY;
yTo = target.y;
}
}
}
/**
* @private
*/
override public function play():void
{
// Dispatch an effectStart event from the target.
super.play();
// Try to cache the target as a bitmap.
EffectManager.startBitmapEffect(IUIComponent(target));
// The user may have supplied some combination of xFrom, xTo, and xBy.
// If either xFrom or xTo is not explicitly defined, calculate its
// value based on the other two values.
if (isNaN(xFrom))
xFrom = (!isNaN(xTo) && !isNaN(xBy)) ? xTo - xBy : target.x;
if (isNaN(xTo))
{
if (isNaN(xBy) &&
propertyChanges &&
propertyChanges.end["x"] !== undefined)
{
xTo = propertyChanges.end["x"];
}
else
{
xTo = (!isNaN(xBy)) ? xFrom + xBy : target.x;
}
}
// Ditto for yFrom, yTo, and yBy.
if (isNaN(yFrom))
yFrom = (!isNaN(yTo) && !isNaN(yBy)) ? yTo - yBy : target.y;
if (isNaN(yTo))
{
if (isNaN(yBy) &&
propertyChanges &&
propertyChanges.end["y"] !== undefined)
{
yTo = propertyChanges.end["y"];
}
else
{
yTo = (!isNaN(yBy)) ? yFrom + yBy : target.y;
}
}
// Create a tween to move the object
tween = createTween(this, [ xFrom, yFrom ],
[ xTo, yTo ], duration);
// Set back to initial position before the screen refreshes
var p:IContainer = target.parent as IContainer;
if (p)
{
var vm:EdgeMetrics = p.viewMetrics;
var l:Number = vm.left;
var r:Number = p.width - vm.right;
var t:Number = vm.top;
var b:Number = p.height - vm.bottom;
if (xFrom < l || xTo < l ||
xFrom + target.width > r || xTo + target.width > r ||
yFrom < t || yTo < t ||
yFrom + target.height > b || yTo + target.height > b)
{
forceClipping = true;
if ("forceClipping" in p)
p["forceClipping"] = true;
}
}
applyTweenStartValues();
if (target is IStyleClient)
{
left = target.getStyle("left");
if (left != undefined)
target.setStyle("left", undefined);
right = target.getStyle("right");
if (right != undefined)
target.setStyle("right", undefined);
top = target.getStyle("top");
if (top != undefined)
target.setStyle("top", undefined);
bottom = target.getStyle("bottom");
if (bottom != undefined)
target.setStyle("bottom", undefined);
horizontalCenter = target.getStyle("horizontalCenter");
if (horizontalCenter != undefined)
target.setStyle("horizontalCenter", undefined);
verticalCenter = target.getStyle("verticalCenter");
if (verticalCenter != undefined)
target.setStyle("verticalCenter", undefined);
if (left != undefined && right != undefined)
{
var w:Number = target.width;
oldWidth = target.explicitWidth;
target.width = w;
}
if (top != undefined && bottom != undefined)
{
var h:Number = target.height;
oldHeight = target.explicitHeight;
target.height = h;
}
}
}
/**
* @private
*/
override public function onTweenUpdate(value:Object):void
{
// Tell the EffectManager not to listen to the "move" event.
// Otherwise, moveEffect="Move" would cause a new Move effect
// to be create with each onTweenUpdate.
EffectManager.suspendEventHandling();
if (!forceClipping && checkClipping)
{
var p:IContainer = target.parent as IContainer;
if (p)
{
var vm:EdgeMetrics = p.viewMetrics;
var l:Number = vm.left;
var r:Number = p.width - vm.right;
var t:Number = vm.top;
var b:Number = p.height - vm.bottom;
if (value[0] < l || value[0] + target.width > r ||
value[1] < t || value[1] + target.height > b)
{
forceClipping = true;
if ("forceClipping" in p)
p["forceClipping"] = true;
}
}
}
target.move(value[0], value[1]);
EffectManager.resumeEventHandling();
}
/**
* @private
*/
override public function onTweenEnd(value:Object):void
{
EffectManager.endBitmapEffect(IUIComponent(target));
if (left != undefined)
target.setStyle("left", left);
if (right != undefined)
target.setStyle("right", right);
if (top != undefined)
target.setStyle("top", top);
if (bottom != undefined)
target.setStyle("bottom", bottom);
if (horizontalCenter != undefined)
target.setStyle("horizontalCenter", horizontalCenter);
if (verticalCenter != undefined)
target.setStyle("verticalCenter", verticalCenter);
if (left != undefined && right != undefined)
{
target.explicitWidth = oldWidth;
}
if (top != undefined && bottom != undefined)
{
target.explicitHeight = oldHeight;
}
if (forceClipping)
{
var p:IContainer = target.parent as IContainer;
if (p)
{
forceClipping = false;
if ("forceClipping" in p)
p["forceClipping"] = false;
}
}
checkClipping = false;
super.onTweenEnd(value);
}
}
}