| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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.utils |
| { |
| import flash.display.DisplayObject; |
| import flash.geom.Point; |
| import flash.geom.Vector3D; |
| |
| import mx.core.AdvancedLayoutFeatures; |
| |
| [ExcludeClass] |
| |
| /** |
| * @private |
| * The TransformUtil class is for internal use only. |
| * It is used for shared code between UIComponent, SpriteVisualElement, and |
| * UIMovieClip. |
| */ |
| public final class TransformUtil |
| { |
| include "../core/Version.as"; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Class methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Returns true if the parameters indicate that AdvancedLayoutFeatures is |
| * needed. |
| */ |
| private static function needAdvancedLayout(transformCenter:Vector3D, |
| scale:Vector3D, |
| rotation:Vector3D, |
| translation:Vector3D, |
| postLayoutScale:Vector3D, |
| postLayoutRotation:Vector3D, |
| postLayoutTranslation:Vector3D):Boolean |
| { |
| var needAdvancedLayout:Boolean = |
| (scale != null && ((!isNaN(scale.x) && scale.x != 1) || |
| (!isNaN(scale.y) && scale.y != 1) || |
| (!isNaN(scale.z) && scale.z != 1))) || |
| (rotation != null && ((!isNaN(rotation.x) && rotation.x != 0) || |
| (!isNaN(rotation.y) && rotation.y != 0) || |
| (!isNaN(rotation.z) && rotation.z != 0))) || |
| (translation != null && translation.z != 0 && !isNaN(translation.z)) || |
| postLayoutScale != null || |
| postLayoutRotation != null || |
| (postLayoutTranslation != null && |
| (translation == null || |
| postLayoutTranslation.x != translation.x || |
| postLayoutTranslation.y != translation.y || |
| postLayoutTranslation.z != translation.z)); |
| |
| return needAdvancedLayout; |
| } |
| |
| private static var xformPt:Point; |
| |
| /** |
| * A utility method to update the rotation, scale, and translation of the |
| * transform while keeping a particular point, specified in the component's |
| * own coordinate space, fixed in the parent's coordinate space. |
| * This function will assign the rotation, scale, and translation values |
| * provided, then update the x/y/z properties as necessary to keep |
| * the transform center fixed. |
| * |
| * If layoutFeatures is specified, then we delegate the calculations to |
| * layoutFeatures. If layoutFeatures is null and an initLayoutFeatures function |
| * is specified, then we use the function to create the layoutFeatures object. |
| */ |
| public static function transformAround(obj:DisplayObject, |
| transformCenter:Vector3D, |
| scale:Vector3D = null, |
| rotation:Vector3D = null, |
| translation:Vector3D = null, |
| postLayoutScale:Vector3D = null, |
| postLayoutRotation:Vector3D = null, |
| postLayoutTranslation:Vector3D = null, |
| layoutFeatures:AdvancedLayoutFeatures = null, |
| initLayoutFeatures:Function = null):void |
| { |
| var needAdvancedLayout:Boolean = (layoutFeatures || |
| TransformUtil.needAdvancedLayout(transformCenter, |
| scale, |
| rotation, |
| translation, |
| postLayoutScale, |
| postLayoutRotation, |
| postLayoutTranslation)); |
| |
| if (needAdvancedLayout) |
| { |
| // TODO (chaase): should provide a way to return to having no |
| // layoutFeatures if we call this later with a more trivial |
| // situation |
| if (!layoutFeatures && initLayoutFeatures != null) |
| layoutFeatures = initLayoutFeatures(); |
| |
| if (layoutFeatures) |
| { |
| layoutFeatures.transformAround(transformCenter, scale, rotation, |
| translation, postLayoutScale, postLayoutRotation, |
| postLayoutTranslation); |
| } |
| return; |
| } |
| |
| if (translation == null && transformCenter != null) |
| { |
| if (xformPt == null) |
| xformPt = new Point(); |
| xformPt.x = transformCenter.x; |
| xformPt.y = transformCenter.y; |
| var xformedPt:Point = |
| obj.transform.matrix.transformPoint(xformPt); |
| } |
| if (rotation != null && !isNaN(rotation.z)) |
| obj.rotation = rotation.z; |
| if (scale != null) |
| { |
| obj.scaleX = scale.x; |
| obj.scaleY = scale.y; |
| } |
| if (transformCenter == null) |
| { |
| if (translation != null) |
| { |
| obj.x = translation.x; |
| obj.y = translation.y; |
| } |
| } |
| else |
| { |
| if (xformPt == null) |
| xformPt = new Point(); |
| xformPt.x = transformCenter.x; |
| xformPt.y = transformCenter.y; |
| var postXFormPoint:Point = |
| obj.transform.matrix.transformPoint(xformPt); |
| if (translation != null) |
| { |
| obj.x += translation.x - postXFormPoint.x; |
| obj.y += translation.y - postXFormPoint.y; |
| } |
| else |
| { |
| obj.x += xformedPt.x - postXFormPoint.x; |
| obj.y += xformedPt.y - postXFormPoint.y; |
| } |
| } |
| } |
| |
| /** |
| * A utility method to transform a point specified in the local |
| * coordinates of the specified object to its location in the object's parent's |
| * coordinates. The pre-layout and post-layout result will be set on |
| * the <code>position</code> and <code>postLayoutPosition</code> |
| * parameters, if they are non-null. |
| * |
| * If layoutFeatures is specified, then we delegate the calculations to |
| * layoutFeatures. |
| * |
| * @param obj The object whose local coordinates are used to transform the point. |
| * @param localPosition The point to be transformed, specified in the |
| * local coordinates of the object. |
| * @param position A Vector3D point that will hold the pre-layout |
| * result. If null, the parameter is ignored. |
| * @param postLayoutPosition A Vector3D point that will hold the post-layout |
| * result. If null, the parameter is ignored. |
| * @param layoutFeatures The layoutFeatures object to delegate these calculations to. |
| */ |
| public static function transformPointToParent(obj:DisplayObject, |
| localPosition:Vector3D, |
| position:Vector3D, |
| postLayoutPosition:Vector3D, |
| layoutFeatures:AdvancedLayoutFeatures):void |
| { |
| if (layoutFeatures) |
| { |
| layoutFeatures.transformPointToParent(true, localPosition, |
| position, postLayoutPosition); |
| return; |
| } |
| |
| if (xformPt == null) |
| xformPt = new Point(); |
| if (localPosition) |
| { |
| xformPt.x = localPosition.x; |
| xformPt.y = localPosition.y; |
| } |
| else |
| { |
| xformPt.x = 0; |
| xformPt.y = 0; |
| } |
| var tmp:Point = (obj.transform.matrix != null) ? |
| obj.transform.matrix.transformPoint(xformPt) : |
| xformPt; |
| if (position != null) |
| { |
| position.x = tmp.x; |
| position.y = tmp.y; |
| position.z = 0; |
| } |
| if (postLayoutPosition != null) |
| { |
| postLayoutPosition.x = tmp.x; |
| postLayoutPosition.y = tmp.y; |
| postLayoutPosition.z = 0; |
| } |
| } |
| } |
| } |