1//////////////////////////////////////////////////////////////////////////////// 2// 3// ADOBE SYSTEMS INCORPORATED 4// Copyright 2003-2008 Adobe Systems Incorporated 5// All Rights Reserved. 6// 7// NOTICE: Adobe permits you to use, modify, and distribute this file 8// in accordance with the terms of the license agreement accompanying it. 9// 10//////////////////////////////////////////////////////////////////////////////// 11package mx.geom 12{ 13 import flash.geom.Matrix; 14 import flash.geom.Matrix3D; 15 import __AS3__.vec.Vector; 16 import flash.geom.Vector3D; 17 import flash.events.EventDispatcher; 18 import flash.events.Event; 19 import mx.core.mx_internal; 20 import mx.core.AdvancedLayoutFeatures; 21 import flash.geom.Point; 22 use namespace mx_internal; 23 24 /** 25 * A CompoundTransform represents a 2D or 3D matrix transform. It can be used in the postLayoutTransformOffsets property on a UIComponent or GraphicElement. 26 * 27 * @langversion 3.0 28 * @playerversion Flash 9 29 * @playerversion AIR 1.1 30 * @productversion Flex 3 31 */ 32 public class TransformOffsets extends EventDispatcher 33 { 34 //-------------------------------------------------------------------------- 35 // 36 // Constructor 37 // 38 //-------------------------------------------------------------------------- 39 /** 40 * Constructor. 41 * 42 * @langversion 3.0 43 * @playerversion Flash 9 44 * @playerversion AIR 1.1 45 * @productversion Flex 3 46 */ 47 public function TransformOffsets() 48 { 49 } 50 51 52 53 /** 54 * @private 55 * storage for transform properties. These values are concatenated together with the layout properties to 56 * form the actual computed matrix used to render the object. 57 */ 58 private var _rotationX:Number = 0; 59 private var _rotationY:Number = 0; 60 private var _rotationZ:Number = 0; 61 private var _scaleX:Number = 1; 62 private var _scaleY:Number = 1; 63 private var _scaleZ:Number = 1; 64 private var _x:Number = 0; 65 private var _y:Number = 0; 66 private var _z:Number = 0; 67 68 /** 69 * @private 70 * flags for tracking whether the transform is 3D. A transform is 3D if any of the 3D properties -- rotationX/Y, scaleZ, or z -- are set. 71 */ 72 private static const IS_3D:uint = 0x200; 73 private static const M3D_FLAGS_VALID:uint = 0x400; 74 75 /** 76 * @private 77 * general storage for all of our flags. 78 */ 79 private var _flags:uint = 0; 80 81 /** 82 * @private 83 */ 84 mx_internal var owner:AdvancedLayoutFeatures; 85 //---------------------------------------------------------------------------- 86 87 /** 88 * the x value added to the transform 89 * 90 * @langversion 3.0 91 * @playerversion Flash 9 92 * @playerversion AIR 1.1 93 * @productversion Flex 3 94 */ 95 public function set x(value:Number):void 96 { 97 if (value == _x) 98 return; 99 _x = value; 100 invalidate(false); 101 } 102 /** 103 * @private 104 */ 105 public function get x():Number 106 { 107 return _x; 108 } 109 110 /** 111 * the y value added to the transform 112 * 113 * @langversion 3.0 114 * @playerversion Flash 9 115 * @playerversion AIR 1.1 116 * @productversion Flex 3 117 */ 118 public function set y(value:Number):void 119 { 120 if (value == _y) 121 return; 122 _y = value; 123 invalidate(false); 124 } 125 126 /** 127 * @private 128 */ 129 public function get y():Number 130 { 131 return _y; 132 } 133 134 /** 135 * the z value added to the transform 136 * 137 * @langversion 3.0 138 * @playerversion Flash 9 139 * @playerversion AIR 1.1 140 * @productversion Flex 3 141 */ 142 public function set z(value:Number):void 143 { 144 if (value == _z) 145 return; 146 _z = value; 147 invalidate(true); 148 } 149 150 /** 151 * @private 152 */ 153 public function get z():Number 154 { 155 return _z; 156 } 157 158 //------------------------------------------------------------------------------ 159 160 161 /** 162 * the rotationX, in degrees, added to the transform 163 * 164 * @langversion 3.0 165 * @playerversion Flash 9 166 * @playerversion AIR 1.1 167 * @productversion Flex 3 168 */ 169 public function set rotationX(value:Number):void 170 { 171 if (value == _rotationX) 172 return; 173 _rotationX = value; 174 invalidate(true); 175 } 176 177 /** 178 * @private 179 */ 180 public function get rotationX():Number 181 { 182 return _rotationX; 183 } 184 185 /** 186 * the rotationY, in degrees, added to the transform 187 * 188 * @langversion 3.0 189 * @playerversion Flash 9 190 * @playerversion AIR 1.1 191 * @productversion Flex 3 192 */ 193 public function set rotationY(value:Number):void 194 { 195 if (value == _rotationY) 196 return; 197 _rotationY = value; 198 invalidate(true); 199 } 200 201 /** 202 * @private 203 */ 204 public function get rotationY():Number 205 { 206 return _rotationY; 207 } 208 209 /** 210 * the rotationZ, in degrees, added to the transform 211 * 212 * @langversion 3.0 213 * @playerversion Flash 9 214 * @playerversion AIR 1.1 215 * @productversion Flex 3 216 */ 217 public function set rotationZ(value:Number):void 218 { 219 if (value == _rotationZ) 220 return; 221 _rotationZ = value; 222 invalidate(false); 223 } 224 225 /** 226 * @private 227 */ 228 public function get rotationZ():Number 229 { 230 return _rotationZ; 231 } 232 233 //------------------------------------------------------------------------------ 234 235 236 /** 237 * the multiplier applied to the scaleX of the transform. 238 * 239 * @langversion 3.0 240 * @playerversion Flash 9 241 * @playerversion AIR 1.1 242 * @productversion Flex 3 243 */ 244 public function set scaleX(value:Number):void 245 { 246 if (value == _scaleX) 247 return; 248 _scaleX = value; 249 invalidate(false); 250 } 251 252 /** 253 * @private 254 */ 255 public function get scaleX():Number 256 { 257 return _scaleX; 258 } 259 260 /** 261 * the multiplier applied to the scaleY of the transform. 262 * 263 * @langversion 3.0 264 * @playerversion Flash 9 265 * @playerversion AIR 1.1 266 * @productversion Flex 3 267 */ 268 public function set scaleY(value:Number):void 269 { 270 if (value == _scaleY) 271 return; 272 _scaleY = value; 273 invalidate(false); 274 } 275 276 /** 277 * @private 278 */ 279 public function get scaleY():Number 280 { 281 return _scaleY; 282 } 283 284 285 /** 286 * the multiplier applied to the scaleZ of the transform. 287 * 288 * @langversion 3.0 289 * @playerversion Flash 9 290 * @playerversion AIR 1.1 291 * @productversion Flex 3 292 */ 293 public function set scaleZ(value:Number):void 294 { 295 if (value == _scaleZ) 296 return; 297 _scaleZ = value; 298 invalidate(true); 299 } 300 301 /** 302 * @private 303 */ 304 public function get scaleZ():Number 305 { 306 return _scaleZ; 307 } 308 309 310 /** 311 * @private 312 * returns true if the transform has 3D values. 313 */ 314 mx_internal function get is3D():Boolean 315 { 316 if ((_flags & M3D_FLAGS_VALID) == 0) 317 update3DFlags(); 318 return ((_flags & IS_3D) != 0); 319 } 320 321 322 //------------------------------------------------------------------------------ 323 324 /** 325 * @private 326 * invalidates our various cached values. Any change to the CompoundTransform object that affects 327 * the various transforms should call this function. 328 * @param reason - the code indicating what changes to cause the invalidation. 329 * @param affects3D - a flag indicating whether the change affects the 2D/3D nature of the various transforms. 330 * @param dispatchChangeEvent - if true, the CompoundTransform will dispatch a change indicating that its underlying transforms 331 * have been modified. 332 */ 333 private function invalidate(affects3D:Boolean,dispatchChangeEvent:Boolean = true):void 334 { 335 if (affects3D) 336 _flags &= ~M3D_FLAGS_VALID; 337 338 if (dispatchChangeEvent) 339 dispatchEvent(new Event(Event.CHANGE)); 340 } 341 342 private static const EPSILON:Number = .001; 343 /** 344 * @private 345 * updates the flags that indicate whether the layout, offset, and/or computed transforms are 3D in nature. 346 * Since the user can set either the individual transform properties or the matrices directly, we compute these 347 * flags based on what the current 'source of truth' is for each of these values. 348 */ 349 private function update3DFlags():void 350 { 351 if ((_flags & M3D_FLAGS_VALID) == 0) 352 { 353 var matrixIs3D:Boolean = ( // note that rotationZ is the same as rotation, and not a 3D affecting 354 (Math.abs(_scaleZ-1) > EPSILON) || // property. 355 ((Math.abs(_rotationX)+EPSILON)%360) > 2*EPSILON || 356 ((Math.abs(_rotationY)+EPSILON)%360) > 2*EPSILON || 357 Math.abs(_z) > EPSILON 358 ); 359 if (matrixIs3D) 360 _flags |= IS_3D; 361 else 362 _flags &= ~IS_3D; 363 _flags |= M3D_FLAGS_VALID; 364 } 365 } 366 367} 368} 369