1//////////////////////////////////////////////////////////////////////////////// 2// 3// ADOBE SYSTEMS INCORPORATED 4// Copyright 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//////////////////////////////////////////////////////////////////////////////// 11 12package spark.primitives.supportClasses 13{ 14 15import flash.display.BitmapData; 16import flash.display.BlendMode; 17import flash.display.DisplayObject; 18import flash.display.DisplayObjectContainer; 19import flash.display.Shape; 20import flash.display.Sprite; 21import flash.events.Event; 22import flash.events.EventDispatcher; 23import flash.events.IEventDispatcher; 24import flash.geom.ColorTransform; 25import flash.geom.Matrix; 26import flash.geom.Matrix3D; 27import flash.geom.Point; 28import flash.geom.Rectangle; 29import flash.geom.Transform; 30import flash.geom.Vector3D; 31 32import mx.core.AdvancedLayoutFeatures; 33import mx.core.DesignLayer; 34import mx.core.IInvalidating; 35import mx.core.ILayoutDirectionElement; 36import mx.core.ILayoutElement; 37import mx.core.IMXMLObject; 38import mx.core.IUIComponent; 39import mx.core.IVisualElement; 40import mx.core.LayoutDirection; 41import mx.core.UIComponent; 42import mx.core.UIComponentGlobals; 43import mx.core.mx_internal; 44import mx.events.FlexEvent; 45import mx.events.PropertyChangeEvent; 46import mx.filters.BaseFilter; 47import mx.filters.IBitmapFilter; 48import mx.geom.Transform; 49import mx.geom.TransformOffsets; 50import mx.graphics.shaderClasses.ColorBurnShader; 51import mx.graphics.shaderClasses.ColorDodgeShader; 52import mx.graphics.shaderClasses.ColorShader; 53import mx.graphics.shaderClasses.ExclusionShader; 54import mx.graphics.shaderClasses.HueShader; 55import mx.graphics.shaderClasses.LuminosityShader; 56import mx.graphics.shaderClasses.SaturationShader; 57import mx.graphics.shaderClasses.SoftLightShader; 58import mx.managers.ILayoutManagerClient; 59import mx.utils.MatrixUtil; 60 61import spark.components.supportClasses.InvalidatingSprite; 62import spark.core.DisplayObjectSharingMode; 63import spark.core.IGraphicElement; 64import spark.core.IGraphicElementContainer; 65import spark.core.MaskType; 66import spark.utils.FTETextUtil; 67import spark.utils.MaskUtil; 68 69use namespace mx_internal; 70 71/** 72 * A base class for defining individual graphic elements. Types of graphic elements include: 73 * <ul> 74 * <li>Shapes</li> 75 * <li>Text</li> 76 * <li>Raster images</li> 77 * </ul> 78 * 79 * <p>When defining a graphic element, you specify an explicit size for the element; 80 * that is, you cannot use percentage sizing as you can when specifying the size of a control.</p> 81 * 82 * <p>The TBounds are the boundaries of an 83 * object in the object's parent coordinate space. The UBounds are the boundaries 84 * of an object in its own coordinate space.</p> 85 * 86 * <p>If you set the transform.matrix declaratively in MXML, then it will override 87 * the values of any transform properties (rotation, scaleX, scaleY, x, and y). 88 * If you set the transform.matrix or the transform properties in ActionScript, then 89 * the last value set will be used.</p> 90 * 91 * @langversion 3.0 92 * @playerversion Flash 10 93 * @playerversion AIR 1.5 94 * @productversion Flex 4 95 */ 96public class GraphicElement extends EventDispatcher 97 implements IGraphicElement, IInvalidating, ILayoutElement, IVisualElement, IMXMLObject 98{ 99 include "../../core/Version.as"; 100 101 //-------------------------------------------------------------------------- 102 // 103 // Class constants 104 // 105 //-------------------------------------------------------------------------- 106 107 /** 108 * @private 109 * The default value for the <code>maxWidth</code> property. 110 */ 111 private static const DEFAULT_MAX_WIDTH:Number = 10000; 112 113 /** 114 * @private 115 * The default value for the <code>maxHeight</code> property. 116 */ 117 private static const DEFAULT_MAX_HEIGHT:Number = 10000; 118 119 /** 120 * @private 121 * The default value for the <code>minWidth</code> property. 122 */ 123 private static const DEFAULT_MIN_WIDTH:Number = 0; 124 125 /** 126 * @private 127 * The default value for the <code>minHeight</code> property. 128 */ 129 private static const DEFAULT_MIN_HEIGHT:Number = 0; 130 131 //-------------------------------------------------------------------------- 132 // 133 // Constructor 134 // 135 //-------------------------------------------------------------------------- 136 137 /** 138 * @private 139 */ 140 public function GraphicElement() 141 { 142 super(); 143 } 144 145 //-------------------------------------------------------------------------- 146 // 147 // Variables 148 // 149 //-------------------------------------------------------------------------- 150 151 /** 152 * @private 153 */ 154 private var displayObjectChanged:Boolean; 155 156 /** 157 * @private 158 */ 159 private var _colorTransform:ColorTransform; 160 161 private var colorTransformChanged:Boolean; 162 163 /** 164 * @private The Sprite to draw into. 165 * If null, then we just use displayObject or sharedDisplayObject 166 */ 167 private var _drawnDisplayObject:InvalidatingSprite; 168 169 /** 170 * @private 171 * Whether this element needs to have its 172 * commitProperties() method called. 173 */ 174 mx_internal var invalidatePropertiesFlag:Boolean = false; 175 176 /** 177 * @private 178 * Whether this element needs to have its 179 * measure() method called. 180 */ 181 mx_internal var invalidateSizeFlag:Boolean = false; 182 183 /** 184 * @private 185 * Whether this element needs to be have its 186 * updateDisplayList() method called. 187 */ 188 mx_internal var invalidateDisplayListFlag:Boolean = false; 189 190 191 /** 192 * Contain all of the implementation details of how the GraphicElement implements 193 * transform and layering support. In most cases, you should not have to modify this 194 * property. 195 * 196 * @langversion 3.0 197 * @playerversion Flash 10 198 * @playerversion AIR 1.5 199 * @productversion Flex 4 200 */ 201 protected var layoutFeatures:AdvancedLayoutFeatures; 202 203 204 /** 205 * @private 206 * storage for the x property. This property is used when a GraphicElement has a simple transform. 207 */ 208 private var _x:Number = 0; 209 210 /** 211 * @private 212 * storage for the y property. This property is used when a GraphicElement has a simple transform. 213 */ 214 private var _y:Number = 0; 215 216 //-------------------------------------------------------------------------- 217 // 218 // Properties 219 // 220 //-------------------------------------------------------------------------- 221 222 /** 223 * @copy mx.core.IVisualElement#postLayoutTransformOffsets 224 * 225 * @langversion 3.0 226 * @playerversion Flash 10 227 * @playerversion AIR 1.5 228 * @productversion Flex 4 229 */ 230 public function get postLayoutTransformOffsets():TransformOffsets 231 { 232 return (layoutFeatures == null)? null:layoutFeatures.postLayoutTransformOffsets; 233 } 234 235 /** 236 * @private 237 */ 238 public function set postLayoutTransformOffsets(value:TransformOffsets):void 239 { 240 if (value != null) 241 allocateLayoutFeatures(); 242 243 if (layoutFeatures.postLayoutTransformOffsets != null) 244 layoutFeatures.postLayoutTransformOffsets.removeEventListener(Event.CHANGE,transformOffsetsChangedHandler); 245 layoutFeatures.postLayoutTransformOffsets = value; 246 if (layoutFeatures.postLayoutTransformOffsets != null) 247 layoutFeatures.postLayoutTransformOffsets.addEventListener(Event.CHANGE,transformOffsetsChangedHandler); 248 } 249 250 /** 251 * @private 252 */ 253 mx_internal function allocateLayoutFeatures():void 254 { 255 if (layoutFeatures != null) 256 return; 257 layoutFeatures = new AdvancedLayoutFeatures(); 258 layoutFeatures.layoutX = _x; 259 layoutFeatures.layoutY = _y; 260 layoutFeatures.layoutWidth = _width; // for the mirror transform 261 } 262 263 /** 264 * @private 265 */ 266 private function invalidateTransform(changeInvalidatesLayering:Boolean = true, 267 invalidateLayout:Boolean = true):void 268 { 269 if (changeInvalidatesLayering) 270 invalidateDisplayObjectSharing(); 271 272 // Make sure we apply the transform 273 if (layoutFeatures != null) 274 layoutFeatures.updatePending = true; 275 276 // If we are sharing a display object we need to redraw 277 if (displayObjectSharingMode != DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT) 278 invalidateDisplayList(); 279 else 280 invalidateProperties(); // We apply the transform in commitProperties 281 282 // Trigger a layout pass 283 if (invalidateLayout) 284 invalidateParentSizeAndDisplayList(); 285 } 286 287 /** 288 * @private 289 */ 290 private function transformOffsetsChangedHandler(e:Event):void 291 { 292 invalidateTransform(); 293 } 294 295 //---------------------------------- 296 // alpha 297 //---------------------------------- 298 299 /** 300 * @private 301 * Storage for the alpha property. 302 */ 303 private var _alpha:Number = 1.0; 304 private var _effectiveAlpha:Number = 1.0; 305 306 /** 307 * @private 308 */ 309 private var alphaChanged:Boolean = false; 310 311 [Inspectable(category="General", minValue="0.0", maxValue="1.0")] 312 313 /** 314 * The level of transparency of the graphic element. Valid values are decimal values between 315 * 0 (fully transparent) and 1 (fully opaque). For example, a value of .25 means that the 316 * element has 25% opacity. 317 * 318 * @langversion 3.0 319 * @playerversion Flash 10 320 * @playerversion AIR 1.5 321 * @productversion Flex 4 322 */ 323 public function get alpha():Number 324 { 325 return _alpha; 326 } 327 328 /** 329 * @private 330 */ 331 public function set alpha(value:Number):void 332 { 333 if (_alpha == value) 334 return; 335 336 var previous:Boolean = needsDisplayObject; 337 _alpha = value; 338 339 // The product of _alpha and the designLayer's 340 // alpha is the effectiveAlpha which is 341 // committed in commitProperties() 342 if (designLayer) 343 value = value * designLayer.effectiveAlpha; 344 345 if (_blendMode == "auto") 346 { 347 // If alpha changes from an opaque/transparent (1/0) and translucent 348 // (0 < value < 1), then trigger a blendMode change 349 if ((value > 0 && value < 1 && (_effectiveAlpha == 0 || _effectiveAlpha == 1)) || 350 ((value == 0 || value == 1) && (_effectiveAlpha > 0 && _effectiveAlpha < 1))) 351 { 352 blendModeChanged = true; 353 } 354 } 355 356 _effectiveAlpha = value; 357 358 // Clear the colorTransform flag since alpha was explicitly set 359 var mxTransform:mx.geom.Transform = _transform as mx.geom.Transform; 360 if (mxTransform) 361 mxTransform.applyColorTransformAlpha = false; 362 363 if (previous != needsDisplayObject) 364 invalidateDisplayObjectSharing(); 365 366 alphaChanged = true; 367 invalidateProperties(); 368 } 369 370 //---------------------------------- 371 // alwaysCreateDisplayObject 372 //---------------------------------- 373 374 private var _alwaysCreateDisplayObject:Boolean; 375 376 /** 377 * Specifies that this GraphicElement is to be associated with and be rendered 378 * to its own DisplayObject. 379 * 380 * @default false 381 * 382 * @langversion 3.0 383 * @playerversion Flash 10 384 * @playerversion AIR 1.5 385 * @productversion Flex 4.5 386 */ 387 public function get alwaysCreateDisplayObject():Boolean 388 { 389 return _alwaysCreateDisplayObject; 390 } 391 392 /** 393 * @private 394 */ 395 public function set alwaysCreateDisplayObject(value:Boolean):void 396 { 397 if (value != _alwaysCreateDisplayObject) 398 { 399 var previous:Boolean = needsDisplayObject; 400 _alwaysCreateDisplayObject = value; 401 if (previous != needsDisplayObject) 402 invalidateDisplayObjectSharing(); 403 } 404 } 405 406 //---------------------------------- 407 // baseline 408 //---------------------------------- 409 410 /** 411 * @private 412 * Storage for the baseline property. 413 */ 414 private var _baseline:Object; 415 416 [Inspectable(category="General")] 417 418 /** 419 * @inheritDoc 420 * 421 * @langversion 3.0 422 * @playerversion Flash 10 423 * @playerversion AIR 1.5 424 * @productversion Flex 4 425 */ 426 public function get baseline():Object 427 { 428 return _baseline; 429 } 430 431 /** 432 * @private 433 */ 434 public function set baseline(value:Object):void 435 { 436 if (_baseline == value) 437 return; 438 439 _baseline = value; 440 invalidateParentSizeAndDisplayList(); 441 } 442 443 //---------------------------------- 444 // baselinePosition 445 //---------------------------------- 446 447 [Inspectable(category="General")] 448 449 /** 450 * The y-coordinate of the baseline 451 * of the first line of text of the component. 452 * 453 * @langversion 3.0 454 * @playerversion Flash 10 455 * @playerversion AIR 1.5 456 * @productversion Flex 4 457 */ 458 public function get baselinePosition():Number 459 { 460 // Subclasses of GraphicElement should return something 461 // here as appropriate (e.g. text centric GraphicElements). 462 var parentUIC:UIComponent = parent as UIComponent; 463 464 if (parentUIC) 465 { 466 if (!parentUIC.validateBaselinePosition()) 467 return NaN; 468 469 return FTETextUtil.calculateFontBaseline(parentUIC, height, parentUIC.moduleFactory); 470 } 471 472 return 0; 473 } 474 475 //---------------------------------- 476 // blendMode 477 //---------------------------------- 478 479 /** 480 * @private 481 * Storage for the blendMode property. 482 */ 483 private var _blendMode:String = "auto"; 484 485 /** 486 * @private 487 */ 488 private var blendModeChanged:Boolean; 489 private var blendShaderChanged:Boolean; 490 private var blendModeExplicitlySet:Boolean = false; 491 492 [Inspectable(category="General", enumeration="auto,add,alpha,darken,difference,erase,hardlight,invert,layer,lighten,multiply,normal,subtract,screen,overlay,colordodge,colorburn,exclusion,softlight,hue,saturation,color,luminosity", defaultValue="auto")] 493 494 /** 495 * A value from the BlendMode class that specifies which blend mode to use. 496 * 497 * @default auto 498 * 499 * @see flash.display.DisplayObject#blendMode 500 * @see flash.display.BlendMode 501 * 502 * @langversion 3.0 503 * @playerversion Flash 10 504 * @playerversion AIR 1.5 505 * @productversion Flex 4 506 */ 507 public function get blendMode():String 508 { 509 return _blendMode; 510 } 511 512 /** 513 * @private 514 */ 515 public function set blendMode(value:String):void 516 { 517 if (value == _blendMode) 518 return; 519 520 var oldValue:String = _blendMode; 521 522 _blendMode = value; 523 blendModeChanged = true; 524 525 // If one of the non-native Flash blendModes is set, 526 // record the new value and set the appropriate 527 // blendShader on the display object. 528 if (isAIMBlendMode(value)) 529 { 530 blendShaderChanged = true; 531 } 532 533 // Only need to re-do display object assignment if blendmode was normal 534 // and is changing to something else, or the blend mode was something else 535 // and is going back to normal. This is because display object sharing 536 // only happens when blendMode is normal. 537 if ((oldValue == BlendMode.NORMAL || value == BlendMode.NORMAL) && 538 !(oldValue == BlendMode.NORMAL && value == BlendMode.NORMAL)) 539 { 540 invalidateDisplayObjectSharing(); 541 } 542 543 invalidateProperties(); 544 } 545 546 //---------------------------------- 547 // bottom 548 //---------------------------------- 549 550 /** 551 * @private 552 * Storage for the bottom property. 553 */ 554 private var _bottom:Object; 555 556 [Inspectable(category="General")] 557 558 /** 559 * @inheritDoc 560 * 561 * @langversion 3.0 562 * @playerversion Flash 10 563 * @playerversion AIR 1.5 564 * @productversion Flex 4 565 */ 566 public function get bottom():Object 567 { 568 return _bottom; 569 } 570 571 /** 572 * @private 573 */ 574 public function set bottom(value:Object):void 575 { 576 if (_bottom == value) 577 return; 578 579 _bottom = value; 580 invalidateParentSizeAndDisplayList(); 581 } 582 583 //---------------------------------- 584 // owner 585 //---------------------------------- 586 587 /** 588 * @private 589 */ 590 private var _owner:DisplayObjectContainer; 591 592 /** 593 * @inheritDoc 594 * 595 * @langversion 3.0 596 * @playerversion Flash 10 597 * @playerversion AIR 1.5 598 * @productversion Flex 4 599 */ 600 public function get owner():DisplayObjectContainer 601 { 602 return _owner ? _owner : parent; 603 } 604 605 public function set owner(value:DisplayObjectContainer):void 606 { 607 _owner = value; 608 } 609 610 //---------------------------------- 611 // layer 612 //---------------------------------- 613 614 /** 615 * @private 616 * Storage for the layer property. 617 */ 618 private var _designLayer:DesignLayer; 619 620 [Inspectable (environment='none')] 621 622 /** 623 * @copy mx.core.IVisualElement#designLayer 624 * 625 * @langversion 3.0 626 * @playerversion Flash 10 627 * @playerversion AIR 1.5 628 * @productversion Flex 4 629 */ 630 public function get designLayer():DesignLayer 631 { 632 return _designLayer; 633 } 634 635 /** 636 * @private 637 */ 638 public function set designLayer(value:DesignLayer):void 639 { 640 if (_designLayer) 641 _designLayer.removeEventListener("layerPropertyChange", layer_PropertyChange, false); 642 643 _designLayer = value; 644 645 if (_designLayer) 646 _designLayer.addEventListener("layerPropertyChange", layer_PropertyChange, false, 0, true); 647 648 _effectiveAlpha = _designLayer ? _alpha * _designLayer.effectiveAlpha : _alpha; 649 _effectiveVisibility = _designLayer ? _visible && _designLayer.effectiveVisibility : _visible; 650 alphaChanged = true; 651 visibleChanged = true; 652 invalidateProperties(); 653 } 654 655 //---------------------------------- 656 // parent 657 //---------------------------------- 658 659 /** 660 * @private 661 * Storage for the parent property. 662 */ 663 private var _parent:IGraphicElementContainer; 664 665 /** 666 * @inheritDoc 667 * 668 * @langversion 3.0 669 * @playerversion Flash 10 670 * @playerversion AIR 1.5 671 * @productversion Flex 4 672 */ 673 public function get parent():DisplayObjectContainer 674 { 675 return _parent as DisplayObjectContainer; 676 } 677 678 /** 679 * @inheritDoc 680 * 681 * @langversion 3.0 682 * @playerversion Flash 10 683 * @playerversion AIR 1.5 684 * @productversion Flex 4 685 */ 686 public function parentChanged(value:IGraphicElementContainer):void 687 { 688 _parent = value; 689 invalidateLayoutDirection(); 690 691 // if we now have a parent and we need to do some invalidation, let our parent know 692 if (parent) 693 { 694 if (invalidatePropertiesFlag) 695 IGraphicElementContainer(parent).invalidateGraphicElementProperties(this); 696 if (invalidateSizeFlag) 697 IGraphicElementContainer(parent).invalidateGraphicElementSize(this); 698 if (invalidateDisplayListFlag) 699 IGraphicElementContainer(parent).invalidateGraphicElementDisplayList(this); 700 } 701 } 702 703 //---------------------------------- 704 // explicitHeight 705 //---------------------------------- 706 707 /** 708 * @private 709 * Storage for the explicitHeight property. 710 */ 711 private var _explicitHeight:Number; 712 713 [Inspectable(category="General")] 714 715 /** 716 * Number that specifies the explicit height of the component, 717 * in pixels, in the component's coordinates. 718 * 719 * @see mx.core.UIComponent#explicitHeight 720 * 721 * @langversion 3.0 722 * @playerversion Flash 10 723 * @playerversion AIR 1.5 724 * @productversion Flex 4 725 */ 726 public function get explicitHeight():Number 727 { 728 return _explicitHeight; 729 } 730 731 /** 732 * @private 733 */ 734 public function set explicitHeight(value:Number):void 735 { 736 if (_explicitHeight == value) 737 return; 738 739 // height can be pixel or percent, not both 740 if (!isNaN(value)) 741 percentHeight = NaN; 742 743 _explicitHeight = value; 744 745 invalidateSize(); 746 invalidateParentSizeAndDisplayList(); 747 } 748 749 //---------------------------------- 750 // explicitMaxHeight 751 //---------------------------------- 752 753 /** 754 * The maximum recommended height of the component to be considered 755 * by the parent during layout. This value is in the 756 * component's coordinates, in pixels. 757 * 758 * @see mx.core.UIComponent#explicitMaxHeight 759 * 760 * @langversion 3.0 761 * @playerversion Flash 10 762 * @playerversion AIR 1.5 763 * @productversion Flex 4 764 */ 765 public function get explicitMaxHeight():Number { return maxHeight; } 766 public function set explicitMaxHeight(value:Number):void { maxHeight = value; } 767 768 //---------------------------------- 769 // explicitMaxWidth 770 //---------------------------------- 771 772 /** 773 * The maximum recommended width of the component to be considered 774 * by the parent during layout. This value is in the 775 * component's coordinates, in pixels. 776 * 777 * @see mx.core.UIComponent#explicitMaxWidth 778 * 779 * @langversion 3.0 780 * @playerversion Flash 10 781 * @playerversion AIR 1.5 782 * @productversion Flex 4 783 */ 784 public function get explicitMaxWidth():Number { return maxWidth; } 785 public function set explicitMaxWidth(value:Number):void { maxWidth = value; } 786 787 //---------------------------------- 788 // explicitMinHeight 789 //---------------------------------- 790 791 /** 792 * The minimum recommended height of the component to be considered 793 * by the parent during layout. This value is in the 794 * component's coordinates, in pixels. 795 * 796 * @see mx.core.UIComponent#explicitMinHeight 797 * 798 * @langversion 3.0 799 * @playerversion Flash 10 800 * @playerversion AIR 1.5 801 * @productversion Flex 4 802 */ 803 public function get explicitMinHeight():Number { return minHeight; } 804 public function set explicitMinHeight(value:Number):void { minHeight = value; } 805 806 //---------------------------------- 807 // explicitMinWidth 808 //---------------------------------- 809 810 /** 811 * The minimum recommended width of the component to be considered 812 * by the parent during layout. This value is in the 813 * component's coordinates, in pixels. 814 * 815 * @see mx.core.UIComponent#explicitMinWidth 816 * 817 * @langversion 3.0 818 * @playerversion Flash 10 819 * @playerversion AIR 1.5 820 * @productversion Flex 4 821 */ 822 public function get explicitMinWidth():Number { return minWidth; } 823 public function set explicitMinWidth(value:Number):void { minWidth = value; } 824 825 //---------------------------------- 826 // explicitWidth 827 //---------------------------------- 828 829 /** 830 * @private 831 * Storage for the explicitHeight property. 832 */ 833 private var _explicitWidth:Number; 834 835 [Inspectable(category="General")] 836 837 /** 838 * Number that specifies the explicit width of the component, 839 * in pixels, in the component's coordinates. 840 * 841 * @see mx.core.UIComponent#explicitWidth 842 * 843 * @langversion 3.0 844 * @playerversion Flash 10 845 * @playerversion AIR 1.5 846 * @productversion Flex 4 847 */ 848 public function get explicitWidth():Number 849 { 850 return _explicitWidth; 851 } 852 853 /** 854 * @private 855 */ 856 public function set explicitWidth(value:Number):void 857 { 858 if (_explicitWidth == value) 859 return; 860 861 // height can be pixel or percent, not both 862 if (!isNaN(value)) 863 percentWidth = NaN; 864 865 _explicitWidth = value; 866 867 invalidateSize(); 868 invalidateParentSizeAndDisplayList(); 869 } 870 871 //---------------------------------- 872 // filters 873 //---------------------------------- 874 875 /** 876 * @private 877 * Storage for the filters property. 878 */ 879 private var _filters:Array = []; 880 881 /** 882 * @private 883 */ 884 private var filtersChanged:Boolean; 885 886 /** 887 * @private 888 */ 889 private var _clonedFilters:Array; 890 891 [Inspectable(category="General")] 892 893 /** 894 * An indexed array that contains each filter object currently associated with the graphic element. 895 * The mx.filters package contains classes that define specific filters you can use. 896 * 897 * <p>The getter returns a copy of the filters array. The filters property value can only be changed 898 * via the setter.</p> 899 * 900 * @see spark.filters.BevelFilter 901 * @see spark.filters.BlurFilter 902 * @see spark.filters.ColorMatrixFilter 903 * @see spark.filters.ConvolutionFilter 904 * @see spark.filters.DisplacementMapFilter 905 * @see spark.filters.DropShadowFilter 906 * @see spark.filters.GlowFilter 907 * @see spark.filters.GradientBevelFilter 908 * @see spark.filters.GradientFilter 909 * @see spark.filters.GradientGlowFilter 910 * @see spark.filters.ShaderFilter 911 * 912 * @langversion 3.0 913 * @playerversion Flash 10 914 * @playerversion AIR 1.5 915 * @productversion Flex 4 916 */ 917 public function get filters():Array 918 { 919 // Return a copy of the filters to prevent it from being mutated. 920 // The only way to change the filters is through the setter. 921 return _filters.slice(); 922 } 923 924 /** 925 * @private 926 */ 927 public function set filters(value:Array):void 928 { 929 var i:int = 0; 930 var len:int = _filters ? _filters.length : 0; 931 var newLen:int = value ? value.length : 0; 932 var edFilter:IEventDispatcher; 933 934 if (len == 0 && newLen == 0) 935 return; 936 937 // Remove the event listeners on the previous filters 938 for (i = 0; i < len; i++) 939 { 940 edFilter = _filters[i] as IEventDispatcher; 941 if (edFilter) 942 edFilter.removeEventListener(BaseFilter.CHANGE, filterChangedHandler); 943 } 944 945 var previous:Boolean = needsDisplayObject; 946 _filters = value; 947 if (previous != needsDisplayObject) 948 invalidateDisplayObjectSharing(); 949 950 _clonedFilters = []; 951 952 for (i = 0; i < newLen; i++) 953 { 954 if (value[i] is IBitmapFilter) 955 { 956 edFilter = value[i] as IEventDispatcher; 957 if (edFilter) 958 edFilter.addEventListener(BaseFilter.CHANGE, filterChangedHandler); 959 _clonedFilters.push(IBitmapFilter(value[i]).clone()); 960 } 961 else 962 { 963 _clonedFilters.push(value[i]); 964 } 965 } 966 967 filtersChanged = true; 968 invalidateProperties(); 969 } 970 971 //---------------------------------- 972 // height 973 //---------------------------------- 974 975 /** 976 * @private 977 * Storage for the height property. 978 */ 979 mx_internal var _height:Number = 0; 980 981 [Bindable("propertyChange")] 982 [Inspectable(category="General")] 983 [PercentProxy("percentHeight")] 984 985 /** 986 * The height of the graphic element. 987 * 988 * @default 0 989 * 990 * @langversion 3.0 991 * @playerversion Flash 10 992 * @playerversion AIR 1.5 993 * @productversion Flex 4 994 */ 995 public function get height():Number 996 { 997 return _height; 998 } 999 1000 /** 1001 * @private 1002 */ 1003 1004 public function set height(value:Number):void 1005 { 1006 explicitHeight = value; 1007 1008 if (_height == value) 1009 return; 1010 1011 var oldValue:Number = _height; 1012 _height = value; 1013 dispatchPropertyChangeEvent("height", oldValue, value); 1014 1015 // Invalidate the display list, since we're changing the actual height 1016 // and we're not going to correctly detect whether the layout sets 1017 // new actual height different from our previous value. 1018 invalidateDisplayList(); 1019 } 1020 1021 //---------------------------------- 1022 // horizontalCenter 1023 //---------------------------------- 1024 1025 /** 1026 * @private 1027 * Storage for the horizontalCenter property. 1028 */ 1029 private var _horizontalCenter:Object; 1030 1031 [Inspectable(category="General")] 1032 1033 /** 1034 * @inheritDoc 1035 * 1036 * @langversion 3.0 1037 * @playerversion Flash 10 1038 * @playerversion AIR 1.5 1039 * @productversion Flex 4 1040 */ 1041 public function get horizontalCenter():Object 1042 { 1043 return _horizontalCenter; 1044 } 1045 1046 /** 1047 * @private 1048 */ 1049 public function set horizontalCenter(value:Object):void 1050 { 1051 if (_horizontalCenter == value) 1052 return; 1053 1054 _horizontalCenter = value; 1055 invalidateParentSizeAndDisplayList(); 1056 } 1057 1058 //---------------------------------- 1059 // id 1060 //---------------------------------- 1061 1062 /** 1063 * @private 1064 * Storage for the id property. 1065 */ 1066 private var _id:String; 1067 1068 /** 1069 * The identity of the component. 1070 * 1071 * @langversion 3.0 1072 * @playerversion Flash 10 1073 * @playerversion AIR 1.5 1074 * @productversion Flex 4 1075 */ 1076 public function get id():String 1077 { 1078 return _id; 1079 } 1080 1081 /** 1082 * @private 1083 */ 1084 public function set id(value:String):void 1085 { 1086 _id = value; 1087 } 1088 1089 //---------------------------------- 1090 // left 1091 //---------------------------------- 1092 1093 /** 1094 * @private 1095 * Storage for the left property. 1096 */ 1097 private var _left:Object; 1098 1099 [Inspectable(category="General")] 1100 1101 /** 1102 * @inheritDoc 1103 * 1104 * @langversion 3.0 1105 * @playerversion Flash 10 1106 * @playerversion AIR 1.5 1107 * @productversion Flex 4 1108 */ 1109 public function get left():Object 1110 { 1111 return _left; 1112 } 1113 1114 /** 1115 * @private 1116 */ 1117 public function set left(value:Object):void 1118 { 1119 if (_left == value) 1120 return; 1121 1122 _left = value; 1123 invalidateParentSizeAndDisplayList(); 1124 } 1125 1126 //---------------------------------- 1127 // mask 1128 //---------------------------------- 1129 1130 /** 1131 * @private 1132 * Storage for the mask property. 1133 */ 1134 private var _mask:DisplayObject; 1135 1136 /** 1137 * @private 1138 */ 1139 private var maskChanged:Boolean; 1140 1141 [Inspectable(category="General")] 1142 1143 /** 1144 * The calling display object is masked by the specified mask object. 1145 * If, the mask display object is not on the display list, it will be added to the display list 1146 * as a child of the displayObject. The mask object itself is not drawn. 1147 * Set mask to null to remove the mask. 1148 * 1149 * To use another GraphicElement as a mask, wrap the GraphicElement in a Group or other container. 1150 * 1151 * @see flash.display.DisplayObject#mask 1152 * 1153 * @langversion 3.0 1154 * @playerversion Flash 10 1155 * @playerversion AIR 1.5 1156 * @productversion Flex 4 1157 */ 1158 public function get mask():DisplayObject 1159 { 1160 return _mask; 1161 } 1162 1163 /** 1164 * @private 1165 */ 1166 public function set mask(value:DisplayObject):void 1167 { 1168 if (_mask == value) 1169 return; 1170 1171 var oldMask:UIComponent = _mask as UIComponent; 1172 1173 var previous:Boolean = needsDisplayObject; 1174 _mask = value; 1175 1176 // If the old mask was attached by us, then we need to 1177 // undo the attachment logic 1178 if (oldMask && oldMask.$parent === displayObject) 1179 { 1180 if (oldMask.parent is UIComponent) 1181 UIComponent(oldMask.parent).childRemoved(oldMask); 1182 oldMask.$parent.removeChild(oldMask); 1183 } 1184 1185 // Cleanup the drawnDisplayObject mask and _drawnDisplayObject here 1186 // because displayObject (the parent of _drawnDisplayObject) 1187 // might be null in commitProperties 1188 if (!_mask || _mask.parent) 1189 { 1190 if (drawnDisplayObject) 1191 drawnDisplayObject.mask = null; 1192 1193 if (_drawnDisplayObject) 1194 { 1195 if (_drawnDisplayObject.parent) 1196 _drawnDisplayObject.parent.removeChild(_drawnDisplayObject); 1197 _drawnDisplayObject = null; 1198 } 1199 } 1200 1201 maskChanged = true; 1202 maskTypeChanged = true; 1203 if (previous != needsDisplayObject) 1204 invalidateDisplayObjectSharing(); 1205 1206 invalidateProperties(); 1207 invalidateDisplayList(); 1208 } 1209 1210 //---------------------------------- 1211 // maskType 1212 //---------------------------------- 1213 1214 /** 1215 * @private 1216 * Storage for the maskType property. 1217 */ 1218 private var _maskType:String = MaskType.CLIP; 1219 1220 /** 1221 * @private 1222 */ 1223 private var maskTypeChanged:Boolean; 1224 1225 [Inspectable(category="General", enumeration="clip,alpha,luminosity", defaultValue="clip")] 1226 1227 /** 1228 * <p>Defines how the mask is applied to the GraphicElement.</p> 1229 * 1230 * <p>The possible values are <code>MaskType.CLIP</code>, <code>MaskType.ALPHA</code>, and 1231 * <code>MaskType.LUMINOSITY</code>.</p> 1232 * 1233 * <p><strong>Clip Masking</strong></p> 1234 * 1235 * <p>When masking in clip mode, a clipping masks is reduced to 1-bit. This means that a mask will 1236 * not affect the opacity of a pixel in the source content; it either leaves the value unmodified, 1237 * if the corresponding pixel in the mask is has a non-zero alpha value, or makes it fully 1238 * transparent, if the mask pixel value has an alpha value of zero.</p> 1239 * 1240 * <p>When clip masking is used, only the actual path and shape vectors and fills defined by the 1241 * mask are used to determine the effect on the source content. strokes and bitmap filters 1242 * defined on the mask are ignored. Any filled region in the mask is considered filled, and renders 1243 * the source content. The type and parameters of the fill is irrelevant; a solid color fill, 1244 * gradient fill, or bitmap fill in a mask will all render the underlying source content, regardless 1245 * of the alpha values of the mask fill.</p> 1246 * 1247 * <p>BitmapGraphics are treated as bitmap filled rectangles when used in a clipping mask. As a 1248 * result, the alpha channel of the source bitmap is irrelevant when part of a mask -- the bitmap 1249 * affects the mask in the same manner as solid filled rectangle of equivalent dimensions.</p> 1250 * 1251 * <p><strong>Alpha Masking</strong></p> 1252 * 1253 * <p>In alpha mode, the opacity of each pixel in the source content is multiplied by the opacity 1254 * of the corresponding region of the mask. i.e., a pixel in the source content with an opacity of 1255 * 1 that is masked by a region of opacity of .5 will have a resulting opacity of .5. A source pixel 1256 * with an opacity of .8 masked by a region with opacity of .5 will have a resulting opacity of .4.</p> 1257 * 1258 * <p>Conceptually, alpha masking is equivalent to rendering the transformed mask and source content 1259 * into separate RGBA surfaces, and multiplying the alpha channel of the mask content into the alpha 1260 * channel of the source content. All of the mask content is rendered into its surface before 1261 * compositing into the source content's surface. As a result, all FXG features, such as strokes, 1262 * bitmap filters, and fill opacity will affect the final composited content.</p> 1263 * 1264 * <p>When in alpha mode, the alpha channel of any bitmap data is composited normally into the mask 1265 * alpha channel, and will affect the final rendered content. This holds true for both BitmapGraphics 1266 * and bitmap filled shapes and paths.</p> 1267 * 1268 * <p><strong>Luminosity Masking</strong></p> 1269 * 1270 * <p>A luminosity mask, sometimes called a 'soft mask', works very similarly to an alpha mask 1271 * except that both the opacity and RGB color value of a pixel in the source content is multiplied 1272 * by the opacity and RGB color value of the corresponding region in the mask.</p> 1273 * 1274 * <p>Conceptually, luminosity masking is equivalent to rendering the transformed mask and source content 1275 * into separate RGBA surfaces, and multiplying the alpha channel and the RGB color value of the mask 1276 * content into the alpha channel and RGB color value of the source content. All of the mask content is 1277 * rendered into its surface before compositing into the source content's surface. As a result, all FXG 1278 * features, such as strokes, bitmap filters, and fill opacity will affect the final composited 1279 * content.</p> 1280 * 1281 * <p>Luminosity masking is not native to Flash but is common in Adobe Creative Suite tools like Adobe 1282 * Illustrator and Adobe Photoshop. In order to accomplish the visual effect of a luminosity mask in 1283 * Flash-rendered content, a graphic element specifying a luminosity mask actually instantiates a shader 1284 * filter that mimics the visual look of a luminosity mask as rendered in Adobe Creative Suite tools.</p> 1285 * 1286 * <p>Objects being masked by luminosity masks can set properties to control the RGB color value and 1287 * clipping of the mask. See the luminosityInvert and luminosityClip attributes.</p> 1288 * 1289 * @default MaskType.CLIP 1290 * 1291 * @see spark.core.MarkType 1292 * 1293 * @langversion 3.0 1294 * @playerversion Flash 10 1295 * @playerversion AIR 1.5 1296 * @productversion Flex 4 1297 */ 1298 public function get maskType():String 1299 { 1300 return _maskType; 1301 } 1302 1303 /** 1304 * @private 1305 */ 1306 public function set maskType(value:String):void 1307 { 1308 if (_maskType == value) 1309 return; 1310 1311 _maskType = value; 1312 maskTypeChanged = true; 1313 invalidateProperties(); 1314 } 1315 1316 //---------------------------------- 1317 // luminosityInvert 1318 //---------------------------------- 1319 1320 /** 1321 * @private 1322 * Storage for the luminosityInvert property. 1323 */ 1324 private var _luminosityInvert:Boolean = false; 1325 1326 /** 1327 * @private 1328 */ 1329 private var luminositySettingsChanged:Boolean; 1330 1331 [Inspectable(category="General", enumeration="true,false", defaultValue="false")] 1332 1333 /** 1334 * A property that controls the calculation of the RGB 1335 * color value of a graphic element being masked by 1336 * a luminosity mask. If true, the RGB color value of a 1337 * pixel in the source content is inverted and multipled 1338 * by the corresponding region in the mask. If false, 1339 * the source content's pixel's RGB color value is used 1340 * directly. 1341 * 1342 * @default false 1343 * @see #maskType 1344 * 1345 * @langversion 3.0 1346 * @playerversion Flash 10 1347 * @playerversion AIR 1.5 1348 * @productversion Flex 4 1349 */ 1350 public function get luminosityInvert():Boolean 1351 { 1352 return _luminosityInvert; 1353 } 1354 1355 /** 1356 * @private 1357 */ 1358 public function set luminosityInvert(value:Boolean):void 1359 { 1360 if (_luminosityInvert == value) 1361 return; 1362 1363 _luminosityInvert = value; 1364 luminositySettingsChanged = true; 1365 } 1366 1367 //---------------------------------- 1368 // luminosityClip 1369 //---------------------------------- 1370 1371 /** 1372 * @private 1373 * Storage for the luminosityClip property. 1374 */ 1375 private var _luminosityClip:Boolean = false; 1376 1377 [Inspectable(category="General", enumeration="true,false", defaultValue="false")] 1378 1379 /** 1380 * A property that controls whether the luminosity 1381 * mask clips the masked content. This property can 1382 * only have an effect if the graphic element has a 1383 * mask applied to it that is of type 1384 * MaskType.LUMINOSITY. 1385 * 1386 * @default false 1387 * @see #maskType 1388 * 1389 * @langversion 3.0 1390 * @playerversion Flash 10 1391 * @playerversion AIR 1.5 1392 * @productversion Flex 4 1393 */ 1394 public function get luminosityClip():Boolean 1395 { 1396 return _luminosityClip; 1397 } 1398 1399 /** 1400 * @private 1401 */ 1402 public function set luminosityClip(value:Boolean):void 1403 { 1404 if (_luminosityClip == value) 1405 return; 1406 1407 _luminosityClip = value; 1408 luminositySettingsChanged = true; 1409 } 1410 1411 //---------------------------------- 1412 // maxHeight 1413 //---------------------------------- 1414 1415 /** 1416 * @private 1417 * Storage for the maxHeight property. 1418 */ 1419 private var _maxHeight:Number; 1420 1421 [Inspectable(category="General")] 1422 1423 /** 1424 * @copy mx.core.UIComponent#maxHeight 1425 * 1426 * @langversion 3.0 1427 * @playerversion Flash 10 1428 * @playerversion AIR 1.5 1429 * @productversion Flex 4 1430 */ 1431 public function get maxHeight():Number 1432 { 1433 return !isNaN(_maxHeight) ? _maxHeight : DEFAULT_MAX_HEIGHT; 1434 } 1435 1436 /** 1437 * @private 1438 */ 1439 public function set maxHeight(value:Number):void 1440 { 1441 if (_maxHeight == value) 1442 return; 1443 1444 _maxHeight = value; 1445 1446 invalidateSize(); 1447 invalidateParentSizeAndDisplayList(); 1448 } 1449 1450 //---------------------------------- 1451 // maxWidth 1452 //---------------------------------- 1453 1454 /** 1455 * @private 1456 * Storage for the maxHeight property. 1457 */ 1458 mx_internal var _maxWidth:Number; 1459 1460 [Inspectable(category="General")] 1461 1462 /** 1463 * @copy mx.core.UIComponent#maxWidth 1464 * 1465 * @langversion 3.0 1466 * @playerversion Flash 10 1467 * @playerversion AIR 1.5 1468 * @productversion Flex 4 1469 */ 1470 public function get maxWidth():Number 1471 { 1472 return !isNaN(_maxWidth) ? _maxWidth : DEFAULT_MAX_WIDTH; 1473 } 1474 1475 /** 1476 * @private 1477 */ 1478 public function set maxWidth(value:Number):void 1479 { 1480 if (_maxWidth == value) 1481 return; 1482 1483 _maxWidth = value; 1484 1485 invalidateSize(); 1486 invalidateParentSizeAndDisplayList(); 1487 } 1488 1489 //---------------------------------- 1490 // measuredHeight 1491 //---------------------------------- 1492 1493 /** 1494 * @private 1495 * Storage for the measuredHeight property. 1496 */ 1497 private var _measuredHeight:Number = 0; 1498 1499 /** 1500 * @copy mx.core.UIComponent#measuredHeight 1501 * 1502 * @langversion 3.0 1503 * @playerversion Flash 10 1504 * @playerversion AIR 1.5 1505 * @productversion Flex 4 1506 */ 1507 public function get measuredHeight():Number 1508 { 1509 return _measuredHeight; 1510 } 1511 1512 /** 1513 * @private 1514 */ 1515 public function set measuredHeight(value:Number):void 1516 { 1517 _measuredHeight = value; 1518 } 1519 1520 //---------------------------------- 1521 // measuredWidth 1522 //---------------------------------- 1523 1524 /** 1525 * @private 1526 * Storage for the measuredWidth property. 1527 */ 1528 private var _measuredWidth:Number = 0; 1529 1530 /** 1531 * @copy mx.core.UIComponent#measuredWidth 1532 * 1533 * @langversion 3.0 1534 * @playerversion Flash 10 1535 * @playerversion AIR 1.5 1536 * @productversion Flex 4 1537 */ 1538 public function get measuredWidth():Number 1539 { 1540 return _measuredWidth; 1541 } 1542 1543 /** 1544 * @private 1545 */ 1546 public function set measuredWidth(value:Number):void 1547 { 1548 _measuredWidth = value; 1549 } 1550 1551 //---------------------------------- 1552 // measuredX 1553 //---------------------------------- 1554 1555 /** 1556 * @private 1557 * Storage for the measuredX property. 1558 */ 1559 private var _measuredX:Number = 0; 1560 1561 /** 1562 * The default measured bounds top-left corner relative to the origin of the element. 1563 * 1564 * @langversion 3.0 1565 * @playerversion Flash 10 1566 * @playerversion AIR 1.5 1567 * @productversion Flex 4 1568 */ 1569 public function get measuredX():Number 1570 { 1571 return _measuredX; 1572 } 1573 1574 /** 1575 * @private 1576 */ 1577 public function set measuredX(value:Number):void 1578 { 1579 _measuredX = value; 1580 } 1581 1582 //---------------------------------- 1583 // measuredY 1584 //---------------------------------- 1585 1586 /** 1587 * @private 1588 * Storage for the measuredY property. 1589 */ 1590 private var _measuredY:Number = 0; 1591 1592 /** 1593 * The default measured bounds top-left corner relative to the origin of the element. 1594 * 1595 * @langversion 3.0 1596 * @playerversion Flash 10 1597 * @playerversion AIR 1.5 1598 * @productversion Flex 4 1599 */ 1600 public function get measuredY():Number 1601 { 1602 return _measuredY; 1603 } 1604 1605 /** 1606 * @private 1607 */ 1608 public function set measuredY(value:Number):void 1609 { 1610 _measuredY = value; 1611 } 1612 1613 //---------------------------------- 1614 // minHeight 1615 //---------------------------------- 1616 1617 /** 1618 * @private 1619 * Storage for the minHeight property. 1620 */ 1621 private var _minHeight:Number; 1622 1623 [Inspectable(category="General")] 1624 1625 /** 1626 * @copy mx.core.UIComponent#minHeight 1627 * 1628 * @langversion 3.0 1629 * @playerversion Flash 10 1630 * @playerversion AIR 1.5 1631 * @productversion Flex 4 1632 */ 1633 public function get minHeight():Number 1634 { 1635 return !isNaN(_minHeight) ? _minHeight : DEFAULT_MIN_HEIGHT; 1636 } 1637 1638 /** 1639 * @private 1640 */ 1641 public function set minHeight(value:Number):void 1642 { 1643 if (_minHeight == value) 1644 return; 1645 1646 _minHeight = value; 1647 1648 invalidateSize(); 1649 invalidateParentSizeAndDisplayList(); 1650 } 1651 1652 //---------------------------------- 1653 // minWidth 1654 //---------------------------------- 1655 1656 /** 1657 * @private 1658 * Storage for the minWidth property. 1659 */ 1660 private var _minWidth:Number; 1661 1662 [Inspectable(category="General")] 1663 1664 /** 1665 * @copy mx.core.UIComponent#minWidth 1666 * 1667 * @langversion 3.0 1668 * @playerversion Flash 10 1669 * @playerversion AIR 1.5 1670 * @productversion Flex 4 1671 */ 1672 public function get minWidth():Number 1673 { 1674 return !isNaN(_minWidth) ? _minWidth : DEFAULT_MIN_WIDTH; 1675 } 1676 1677 /** 1678 * @private 1679 */ 1680 public function set minWidth(value:Number):void 1681 { 1682 if (_minWidth == value) 1683 return; 1684 1685 _minWidth = value; 1686 1687 invalidateSize(); 1688 invalidateParentSizeAndDisplayList(); 1689 } 1690 1691 //---------------------------------- 1692 // percentHeight 1693 //---------------------------------- 1694 1695 /** 1696 * @private 1697 * Storage for the percentHeight property. 1698 */ 1699 private var _percentHeight:Number; 1700 1701 [Inspectable(category="General")] 1702 1703 /** 1704 * @inheritDoc 1705 * 1706 * @langversion 3.0 1707 * @playerversion Flash 10 1708 * @playerversion AIR 1.5 1709 * @productversion Flex 4 1710 */ 1711 public function get percentHeight():Number 1712 { 1713 return _percentHeight; 1714 } 1715 1716 /** 1717 * @private 1718 */ 1719 public function set percentHeight(value:Number):void 1720 { 1721 if (_percentHeight == value) 1722 return; 1723 1724 if (!isNaN(value)) 1725 explicitHeight = NaN; 1726 1727 _percentHeight = value; 1728 1729 invalidateParentSizeAndDisplayList(); 1730 } 1731 1732 //---------------------------------- 1733 // percentWidth 1734 //---------------------------------- 1735 1736 /** 1737 * @private 1738 * Storage for the percentWidth property. 1739 */ 1740 private var _percentWidth:Number; 1741 1742 [Inspectable(category="General")] 1743 1744 /** 1745 * @copy mx.core.UIComponent#percentWidth 1746 * 1747 * @langversion 3.0 1748 * @playerversion Flash 10 1749 * @playerversion AIR 1.5 1750 * @productversion Flex 4 1751 */ 1752 public function get percentWidth():Number 1753 { 1754 return _percentWidth; 1755 } 1756 1757 /** 1758 * @private 1759 */ 1760 public function set percentWidth(value:Number):void 1761 { 1762 if (_percentWidth == value) 1763 return; 1764 1765 if (!isNaN(value)) 1766 explicitWidth = NaN; 1767 1768 _percentWidth = value; 1769 1770 invalidateParentSizeAndDisplayList(); 1771 } 1772 1773 //---------------------------------- 1774 // right 1775 //---------------------------------- 1776 1777 /** 1778 * @private 1779 * Storage for the right property. 1780 */ 1781 private var _right:Object; 1782 1783 [Inspectable(category="General")] 1784 1785 /** 1786 * @inheritDoc 1787 * 1788 * @langversion 3.0 1789 * @playerversion Flash 10 1790 * @playerversion AIR 1.5 1791 * @productversion Flex 4 1792 */ 1793 public function get right():Object 1794 { 1795 return _right; 1796 } 1797 1798 /** 1799 * @private 1800 */ 1801 public function set right(value:Object):void 1802 { 1803 if (_right == value) 1804 return; 1805 1806 _right = value; 1807 invalidateParentSizeAndDisplayList(); 1808 } 1809 1810 //---------------------------------- 1811 // rotation 1812 //---------------------------------- 1813 1814 [Inspectable(category="General")] 1815 1816 /** 1817 * Indicates the x-axis rotation of the element instance, in degrees, from its original orientation 1818 * relative to the 3D parent container. Values from 0 to 180 represent clockwise rotation; values 1819 * from 0 to -180 represent counterclockwise rotation. Values outside this range are added to or subtracted from 1820 * 360 to obtain a value within the range. 1821 * 1822 * This property is ignored during calculation by any of Flex's 2D layouts. 1823 * 1824 * @langversion 3.0 1825 * @playerversion Flash 10 1826 * @playerversion AIR 1.5 1827 * @productversion Flex 4 1828 */ 1829 public function get rotationX():Number 1830 { 1831 return (layoutFeatures == null)? 0:layoutFeatures.layoutRotationX; 1832 } 1833 1834 /** 1835 * @private 1836 */ 1837 public function set rotationX(value:Number):void 1838 { 1839 if (rotationX == value) 1840 return; 1841 1842 allocateLayoutFeatures(); 1843 var previous:Boolean = needsDisplayObject; 1844 layoutFeatures.layoutRotationX = value; 1845 invalidateTransform(previous != needsDisplayObject); 1846 } 1847 1848 [Inspectable(category="General")] 1849 1850 /** 1851 * Indicates the y-axis rotation of the DisplayObject instance, in degrees, from its original orientation 1852 * relative to the 3D parent container. Values from 0 to 180 represent clockwise rotation; values 1853 * from 0 to -180 represent counterclockwise rotation. Values outside this range are added to or subtracted from 1854 * 360 to obtain a value within the range. 1855 * 1856 * This property is ignored during calculation by any of Flex's 2D layouts. 1857 * 1858 * @langversion 3.0 1859 * @playerversion Flash 10 1860 * @playerversion AIR 1.5 1861 * @productversion Flex 4 1862 */ 1863 public function get rotationY():Number 1864 { 1865 return (layoutFeatures == null)? 0:layoutFeatures.layoutRotationY; 1866 } 1867 /** 1868 * @private 1869 */ 1870 public function set rotationY(value:Number):void 1871 { 1872 if (rotationY == value) 1873 return; 1874 1875 allocateLayoutFeatures(); 1876 var previous:Boolean = needsDisplayObject; 1877 layoutFeatures.layoutRotationY = value; 1878 invalidateTransform(previous != needsDisplayObject); 1879 } 1880 1881 [Inspectable(category="General")] 1882 1883 /** 1884 * Indicates the rotation of the element, in degrees, 1885 * from the transform point. 1886 * 1887 * @langversion 3.0 1888 * @playerversion Flash 10 1889 * @playerversion AIR 1.5 1890 * @productversion Flex 4 1891 */ 1892 public function get rotationZ():Number 1893 { 1894 return (layoutFeatures == null)? 0:layoutFeatures.layoutRotationZ; 1895 } 1896 1897 /** 1898 * @private 1899 */ 1900 public function set rotationZ(value:Number):void 1901 { 1902 if (rotationZ == value) 1903 return; 1904 1905 allocateLayoutFeatures(); 1906 var previous:Boolean = needsDisplayObject; 1907 layoutFeatures.layoutRotationZ = value; 1908 invalidateTransform(previous != needsDisplayObject); 1909 } 1910 1911 [Inspectable(category="General")] 1912 1913 /** 1914 * Indicates the rotation of the element, in degrees, 1915 * from the transform point. 1916 * 1917 * @langversion 3.0 1918 * @playerversion Flash 10 1919 * @playerversion AIR 1.5 1920 * @productversion Flex 4 1921 */ 1922 public function get rotation():Number 1923 { 1924 return (layoutFeatures == null)? 0:layoutFeatures.layoutRotationZ; 1925 } 1926 1927 /** 1928 * @private 1929 */ 1930 public function set rotation(value:Number):void 1931 { 1932 rotationZ = value; 1933 } 1934 1935 //---------------------------------- 1936 // scaleX 1937 //---------------------------------- 1938 1939 [Inspectable(category="General")] 1940 1941 /** 1942 * The horizontal scale (percentage) of the element 1943 * as applied from the transform point. 1944 * 1945 * @langversion 3.0 1946 * @playerversion Flash 10 1947 * @playerversion AIR 1.5 1948 * @productversion Flex 4 1949 */ 1950 public function get scaleX():Number 1951 { 1952 return (layoutFeatures == null)? 1:layoutFeatures.layoutScaleX; 1953 } 1954 1955 /** 1956 * @private 1957 */ 1958 public function set scaleX(value:Number):void 1959 { 1960 if (scaleX == value) 1961 return; 1962 1963 allocateLayoutFeatures(); 1964 var previous:Boolean = needsDisplayObject; 1965 layoutFeatures.layoutScaleX = value; 1966 invalidateTransform(previous != needsDisplayObject); 1967 } 1968 1969 //---------------------------------- 1970 // scaleY 1971 //---------------------------------- 1972 1973 [Inspectable(category="General")] 1974 1975 /** 1976 * The vertical scale (percentage) of the element 1977 * as applied from the transform point. 1978 * 1979 * @langversion 3.0 1980 * @playerversion Flash 10 1981 * @playerversion AIR 1.5 1982 * @productversion Flex 4 1983 */ 1984 public function get scaleY():Number 1985 { 1986 return (layoutFeatures == null)? 1:layoutFeatures.layoutScaleY; 1987 } 1988 1989 /** 1990 * @private 1991 */ 1992 public function set scaleY(value:Number):void 1993 { 1994 if (scaleY == value) 1995 return; 1996 1997 allocateLayoutFeatures(); 1998 var previous:Boolean = needsDisplayObject; 1999 layoutFeatures.layoutScaleY = value; 2000 invalidateTransform(previous != needsDisplayObject); 2001 } 2002 2003 //---------------------------------- 2004 // scaleZ 2005 //---------------------------------- 2006 2007 [Inspectable(category="General")] 2008 2009 /** 2010 * The z scale (percentage) of the element 2011 * as applied from the transform point. 2012 * 2013 * @langversion 3.0 2014 * @playerversion Flash 10 2015 * @playerversion AIR 1.5 2016 * @productversion Flex 4 2017 */ 2018 public function get scaleZ():Number 2019 { 2020 return (layoutFeatures == null)? 1:layoutFeatures.layoutScaleZ; 2021 } 2022 2023 /** 2024 * @private 2025 */ 2026 public function set scaleZ(value:Number):void 2027 { 2028 if (scaleZ == value) 2029 return; 2030 2031 allocateLayoutFeatures(); 2032 var previous:Boolean = needsDisplayObject; 2033 layoutFeatures.layoutScaleZ = value; 2034 invalidateTransform(previous != needsDisplayObject); 2035 } 2036 2037 //---------------------------------- 2038 // top 2039 //---------------------------------- 2040 2041 /** 2042 * @private 2043 * Storage for the top property. 2044 */ 2045 private var _top:Object; 2046 2047 [Inspectable(category="General")] 2048 2049 /** 2050 * @inheritDoc 2051 * 2052 * @langversion 3.0 2053 * @playerversion Flash 10 2054 * @playerversion AIR 1.5 2055 * @productversion Flex 4 2056 */ 2057 public function get top():Object 2058 { 2059 return _top; 2060 } 2061 2062 /** 2063 * @private 2064 */ 2065 public function set top(value:Object):void 2066 { 2067 if (_top == value) 2068 return; 2069 2070 _top = value; 2071 invalidateParentSizeAndDisplayList(); 2072 } 2073 2074 //---------------------------------- 2075 // transform 2076 //---------------------------------- 2077 2078 /** 2079 * @private 2080 * Storage for the transform property. 2081 */ 2082 private var _transform:flash.geom.Transform; 2083 2084 /** 2085 * @copy mx.core.IFlexDisplayObject#transform 2086 * 2087 * @langversion 3.0 2088 * @playerversion Flash 10 2089 * @playerversion AIR 1.5 2090 * @productversion Flex 4 2091 */ 2092 public function get transform():flash.geom.Transform 2093 { 2094 if (!_transform) 2095 setTransform(new mx.geom.Transform()); 2096 2097 return _transform; 2098 } 2099 2100 /** 2101 * @private 2102 */ 2103 public function set transform(value:flash.geom.Transform):void 2104 { 2105 // TODO (jszeto): Add perspectiveProjection support 2106 var matrix:Matrix = value && value.matrix ? value.matrix.clone() : null; 2107 var matrix3D:Matrix3D = value && value.matrix3D ? value.matrix3D.clone() : null; 2108 var colorTransform:ColorTransform = value ? value.colorTransform : null; 2109 2110 var mxTransform:mx.geom.Transform = value as mx.geom.Transform; 2111 if (mxTransform) 2112 { 2113 if (!mxTransform.applyMatrix) 2114 matrix = null; 2115 2116 if (!mxTransform.applyMatrix3D) 2117 matrix3D = null; 2118 } 2119 2120 setTransform(value); 2121 2122 var previous:Boolean = needsDisplayObject; 2123 2124 if (_transform) 2125 { 2126 allocateLayoutFeatures(); 2127 2128 if (matrix != null) 2129 { 2130 layoutFeatures.layoutMatrix = matrix; 2131 } 2132 else if (matrix3D != null) 2133 { 2134 layoutFeatures.layoutMatrix3D = matrix3D; 2135 } 2136 } 2137 2138 2139 applyColorTransform(colorTransform, mxTransform && mxTransform.applyColorTransformAlpha); 2140 2141 invalidateTransform(previous != needsDisplayObject); 2142 } 2143 2144 /** 2145 * @private 2146 */ 2147 private function setTransform(value:flash.geom.Transform):void 2148 { 2149 // Clean up the old transform 2150 var oldTransform:mx.geom.Transform = _transform as mx.geom.Transform; 2151 if (oldTransform) 2152 oldTransform.target = null; 2153 2154 var newTransform:mx.geom.Transform = value as mx.geom.Transform; 2155 2156 if (newTransform) 2157 newTransform.target = this; 2158 2159 _transform = value; 2160 } 2161 2162 /** 2163 * @private 2164 * 2165 * Sets the colorTransform property of the transform. Called by mx.geom.Transform 2166 * when its colorTransform property has been changed. 2167 */ 2168 public function setColorTransform(value:ColorTransform):void 2169 { 2170 applyColorTransform(value, true); 2171 } 2172 2173 /** 2174 * @private 2175 */ 2176 private function applyColorTransform(value:ColorTransform, updateAlpha:Boolean):void 2177 { 2178 if (_colorTransform != value) 2179 { 2180 var previous:Boolean = needsDisplayObject; 2181 // Make a copy of the colorTransform 2182 _colorTransform = new ColorTransform(value.redMultiplier, value.greenMultiplier, value.blueMultiplier, value.alphaMultiplier, 2183 value.redOffset, value.greenOffset, value.blueOffset, value.alphaOffset); 2184 2185 if (updateAlpha) 2186 { 2187 _alpha = value.alphaMultiplier; 2188 _effectiveAlpha = _alpha; 2189 } 2190 2191 if (displayObject && displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT) 2192 { 2193 displayObject.transform.colorTransform = _colorTransform; 2194 } 2195 else 2196 { 2197 colorTransformChanged = true; 2198 invalidateProperties(); 2199 if (previous != needsDisplayObject) 2200 invalidateDisplayObjectSharing(); 2201 } 2202 } 2203 } 2204 2205 /** 2206 * @private 2207 */ 2208 private function isAIMBlendMode(value:String):Boolean 2209 { 2210 if (value == "colordodge" || 2211 value =="colorburn" || value =="exclusion" || 2212 value =="softlight" || value =="hue" || 2213 value =="saturation" || value =="color" || 2214 value =="luminosity") 2215 return true; 2216 else return false; 2217 } 2218 2219 /** 2220 * @copy mx.core.ILayoutElement#transformAround() 2221 * 2222 * @langversion 3.0 2223 * @playerversion Flash 10 2224 * @playerversion AIR 1.5 2225 * @productversion Flex 4 2226 */ 2227 public function transformAround(transformCenter:Vector3D, 2228 scale:Vector3D = null, 2229 rotation:Vector3D = null, 2230 translation:Vector3D = null, 2231 postLayoutScale:Vector3D = null, 2232 postLayoutRotation:Vector3D = null, 2233 postLayoutTranslation:Vector3D = null, 2234 invalidateLayout:Boolean = true):void 2235 { 2236 // TODO (egreenfi): optimize for simple translations 2237 allocateLayoutFeatures(); 2238 var previous:Boolean = needsDisplayObject; 2239 var prevX:Number = layoutFeatures.layoutX; 2240 var prevY:Number = layoutFeatures.layoutY; 2241 var prevZ:Number = layoutFeatures.layoutZ; 2242 layoutFeatures.transformAround(transformCenter,scale,rotation,translation,postLayoutScale,postLayoutRotation,postLayoutTranslation); 2243 invalidateTransform(previous != needsDisplayObject, invalidateLayout); 2244 if (prevX != layoutFeatures.layoutX) 2245 dispatchPropertyChangeEvent("x", prevX, layoutFeatures.layoutX); 2246 if (prevY != layoutFeatures.layoutY) 2247 dispatchPropertyChangeEvent("y", prevY, layoutFeatures.layoutY); 2248 if (prevZ != layoutFeatures.layoutZ) 2249 dispatchPropertyChangeEvent("z", prevZ, layoutFeatures.layoutZ); 2250 } 2251 2252 /** 2253 * A utility method to transform a point specified in the local 2254 * coordinates of this object to its location in the object's parent's 2255 * coordinates. The pre-layout and post-layout result will be set on 2256 * the <code>position</code> and <code>postLayoutPosition</code> 2257 * parameters, if they are non-null. 2258 * 2259 * @param localPosition The point to be transformed, specified in the 2260 * local coordinates of the object. 2261 * @param position A Vector3D point that will hold the pre-layout 2262 * result. If null, the parameter is ignored. 2263 * @param postLayoutPosition A Vector3D point that will hold the post-layout 2264 * result. If null, the parameter is ignored. 2265 * 2266 * @langversion 3.0 2267 * @playerversion Flash 10 2268 * @playerversion AIR 1.5 2269 * @productversion Flex 4 2270 */ 2271 public function transformPointToParent(localPosition:Vector3D, 2272 position:Vector3D, 2273 postLayoutPosition:Vector3D):void 2274 { 2275 if (layoutFeatures != null) 2276 { 2277 layoutFeatures.transformPointToParent(true, localPosition, position, 2278 postLayoutPosition); 2279 } 2280 else 2281 { 2282 var xformPt:Point = new Point(); 2283 if (localPosition) 2284 { 2285 xformPt.x = localPosition.x; 2286 xformPt.y = localPosition.y; 2287 } 2288 if (position != null) 2289 { 2290 position.x = xformPt.x + _x; 2291 position.y = xformPt.y + _y; 2292 position.z = 0; 2293 } 2294 if (postLayoutPosition != null) 2295 { 2296 postLayoutPosition.x = xformPt.x + _x; 2297 postLayoutPosition.y = xformPt.y + _y; 2298 postLayoutPosition.z = 0; 2299 } 2300 } 2301 } 2302 2303 //---------------------------------- 2304 // transformX 2305 //---------------------------------- 2306 2307 [Inspectable(category="General")] 2308 2309 /** 2310 * The x position transform point of the element. 2311 * 2312 * @langversion 3.0 2313 * @playerversion Flash 10 2314 * @playerversion AIR 1.5 2315 * @productversion Flex 4 2316 */ 2317 public function get transformX():Number 2318 { 2319 return (layoutFeatures == null)? 0:layoutFeatures.transformX; 2320 } 2321 2322 /** 2323 * @private 2324 */ 2325 public function set transformX(value:Number):void 2326 { 2327 if (transformX == value) 2328 return; 2329 2330 allocateLayoutFeatures(); 2331 layoutFeatures.transformX = value; 2332 invalidateTransform(false); 2333 } 2334 2335 //---------------------------------- 2336 // transformY 2337 //---------------------------------- 2338 2339 [Inspectable(category="General")] 2340 2341 /** 2342 * The y position transform point of the element. 2343 * 2344 * @langversion 3.0 2345 * @playerversion Flash 10 2346 * @playerversion AIR 1.5 2347 * @productversion Flex 4 2348 */ 2349 public function get transformY():Number 2350 { 2351 return (layoutFeatures == null)? 0:layoutFeatures.transformY; 2352 } 2353 2354 /** 2355 * @private 2356 */ 2357 public function set transformY(value:Number):void 2358 { 2359 if (transformY == value) 2360 return; 2361 2362 allocateLayoutFeatures(); 2363 layoutFeatures.transformY = value; 2364 invalidateTransform(false); 2365 } 2366 2367 //---------------------------------- 2368 // transformZ 2369 //---------------------------------- 2370 2371 [Inspectable(category="General")] 2372 2373 /** 2374 * The z position transform point of the element. 2375 * 2376 * @langversion 3.0 2377 * @playerversion Flash 10 2378 * @playerversion AIR 1.5 2379 * @productversion Flex 4 2380 */ 2381 public function get transformZ():Number 2382 { 2383 return (layoutFeatures == null)? 0:layoutFeatures.transformZ; 2384 } 2385 2386 /** 2387 * @private 2388 */ 2389 public function set transformZ(value:Number):void 2390 { 2391 if (transformZ == value) 2392 return; 2393 2394 allocateLayoutFeatures(); 2395 var previous:Boolean = needsDisplayObject; 2396 layoutFeatures.transformZ = value; 2397 invalidateTransform(previous != needsDisplayObject); 2398 } 2399 2400 //---------------------------------- 2401 // verticalCenter 2402 //---------------------------------- 2403 2404 /** 2405 * @private 2406 * Storage for the verticalCenter property. 2407 */ 2408 private var _verticalCenter:Object; 2409 2410 [Inspectable(category="General")] 2411 2412 /** 2413 * @inheritDoc 2414 * 2415 * @langversion 3.0 2416 * @playerversion Flash 10 2417 * @playerversion AIR 1.5 2418 * @productversion Flex 4 2419 */ 2420 public function get verticalCenter():Object 2421 { 2422 return _verticalCenter; 2423 } 2424 2425 /** 2426 * @private 2427 */ 2428 public function set verticalCenter(value:Object):void 2429 { 2430 if (_verticalCenter == value) 2431 return; 2432 2433 _verticalCenter = value; 2434 invalidateParentSizeAndDisplayList(); 2435 } 2436 2437 //---------------------------------- 2438 // width 2439 //---------------------------------- 2440 2441 /** 2442 * @private 2443 * Storage for the width property. 2444 */ 2445 mx_internal var _width:Number = 0; 2446 2447 [Bindable("propertyChange")] 2448 [Inspectable(category="General")] 2449 [PercentProxy("percentWidth")] 2450 2451 /** 2452 * The width of the graphic element. 2453 * 2454 * @default 0 2455 * 2456 * @langversion 3.0 2457 * @playerversion Flash 10 2458 * @playerversion AIR 1.5 2459 * @productversion Flex 4 2460 */ 2461 public function get width():Number 2462 { 2463 return _width; 2464 } 2465 2466 /** 2467 * @private 2468 */ 2469 public function set width(value:Number):void 2470 { 2471 explicitWidth = value; 2472 2473 if (_width == value) 2474 return; 2475 2476 var oldValue:Number = _width; 2477 _width = value; 2478 2479 // The width is needed for the mirroring transform. 2480 if (layoutFeatures) 2481 { 2482 layoutFeatures.layoutWidth = value; 2483 invalidateTransform(); 2484 } 2485 2486 dispatchPropertyChangeEvent("width", oldValue, value); 2487 2488 // Invalidate the display list, since we're changing the actual width 2489 // and we're not going to correctly detect whether the layout sets 2490 // new actual width different from our previous value. 2491 invalidateDisplayList(); 2492 } 2493 2494 //---------------------------------- 2495 // depth 2496 //---------------------------------- 2497 2498 /** 2499 * @inheritDoc 2500 * 2501 * @langversion 3.0 2502 * @playerversion Flash 10 2503 * @playerversion AIR 1.5 2504 * @productversion Flex 4 2505 */ 2506 public function get depth():Number 2507 { 2508 return (layoutFeatures == null) ? 0 : layoutFeatures.depth; 2509 } 2510 2511 /** 2512 * @private 2513 */ 2514 public function set depth(value:Number):void 2515 { 2516 if (value == depth) 2517 return; 2518 2519 allocateLayoutFeatures(); 2520 layoutFeatures.depth = value; 2521 if (_parent is UIComponent) 2522 UIComponent(_parent).invalidateLayering(); 2523 invalidateProperties(); 2524 } 2525 2526 //---------------------------------- 2527 // x 2528 //---------------------------------- 2529 2530 [Bindable("propertyChange")] 2531 [Inspectable(category="General")] 2532 2533 /** 2534 * The x position of the graphic element. 2535 * 2536 * @langversion 3.0 2537 * @playerversion Flash 10 2538 * @playerversion AIR 1.5 2539 * @productversion Flex 4 2540 */ 2541 public function get x():Number 2542 { 2543 return (layoutFeatures == null)? _x:layoutFeatures.layoutX; 2544 } 2545 2546 /** 2547 * @private 2548 */ 2549 public function set x(value:Number):void 2550 { 2551 var oldValue:Number = x; 2552 if (oldValue == value) 2553 return; 2554 2555 if (layoutFeatures != null) 2556 layoutFeatures.layoutX = value; 2557 else 2558 _x = value; 2559 2560 dispatchPropertyChangeEvent("x", oldValue, value); 2561 invalidateTransform(false); 2562 } 2563 2564 //---------------------------------- 2565 // y 2566 //---------------------------------- 2567 2568 [Bindable("propertyChange")] 2569 [Inspectable(category="General")] 2570 2571 /** 2572 * The y position of the graphic element. 2573 * 2574 * @langversion 3.0 2575 * @playerversion Flash 10 2576 * @playerversion AIR 1.5 2577 * @productversion Flex 4 2578 */ 2579 public function get y():Number 2580 { 2581 return (layoutFeatures == null)? _y:layoutFeatures.layoutY; 2582 } 2583 2584 /** 2585 * @private 2586 */ 2587 public function set y(value:Number):void 2588 { 2589 var oldValue:Number = y; 2590 if (oldValue == value) 2591 return; 2592 2593 if (layoutFeatures != null) 2594 layoutFeatures.layoutY = value; 2595 else 2596 _y = value; 2597 dispatchPropertyChangeEvent("y", oldValue, value); 2598 invalidateTransform(false); 2599 } 2600 2601 //---------------------------------- 2602 // z 2603 //---------------------------------- 2604 2605 [Bindable("propertyChange")] 2606 [Inspectable(category="General")] 2607 2608 /** 2609 * The z position of the graphic element. 2610 * 2611 * @langversion 3.0 2612 * @playerversion Flash 10 2613 * @playerversion AIR 1.5 2614 * @productversion Flex 4 2615 */ 2616 public function get z():Number 2617 { 2618 return (layoutFeatures == null)? 0:layoutFeatures.layoutZ; 2619 } 2620 2621 /** 2622 * @private 2623 */ 2624 public function set z(value:Number):void 2625 { 2626 if (z == value) 2627 return; 2628 var oldValue:Number = z; 2629 2630 allocateLayoutFeatures(); 2631 var previous:Boolean = needsDisplayObject; 2632 layoutFeatures.layoutZ = value; 2633 invalidateTransform(previous != needsDisplayObject); 2634 dispatchPropertyChangeEvent("z", oldValue, value); 2635 } 2636 2637 //---------------------------------- 2638 // visible 2639 //---------------------------------- 2640 2641 /** 2642 * @private 2643 * Storage for the visible property. 2644 */ 2645 private var _visible:Boolean = true; 2646 2647 2648 /** 2649 * @private 2650 * The actual 'effective' visibility of this 2651 * element, one that considers the visibility of 2652 * the owning design layer parent (if any). 2653 */ 2654 protected var _effectiveVisibility:Boolean = true; 2655 2656 /** 2657 * @private 2658 */ 2659 private var visibleChanged:Boolean; 2660 2661 [Inspectable(category="General")] 2662 2663 /** 2664 * @inheritDoc 2665 * 2666 * @langversion 3.0 2667 * @playerversion Flash 10 2668 * @playerversion AIR 1.5 2669 * @productversion Flex 4 2670 */ 2671 public function get visible():Boolean 2672 { 2673 return _visible; 2674 } 2675 2676 /** 2677 * @private 2678 */ 2679 public function set visible(value:Boolean):void 2680 { 2681 _visible = value; 2682 2683 if (designLayer && !designLayer.effectiveVisibility) 2684 value = false; 2685 2686 if (_effectiveVisibility == value) 2687 return; 2688 2689 _effectiveVisibility = value; 2690 visibleChanged = true; 2691 invalidateProperties(); 2692 } 2693 2694 //-------------------------------------------------------------------------- 2695 // 2696 // Properties: IDisplayObjectElement 2697 // 2698 //-------------------------------------------------------------------------- 2699 2700 //---------------------------------- 2701 // displayObject 2702 //---------------------------------- 2703 2704 /** 2705 * @private 2706 * Storage for the displayObject property. 2707 */ 2708 private var _displayObject:DisplayObject; 2709 2710 [Bindable("propertyChange")] 2711 [Inspectable(category="General")] 2712 2713 /** 2714 * @inheritDoc 2715 * 2716 * @langversion 3.0 2717 * @playerversion Flash 10 2718 * @playerversion AIR 1.5 2719 * @productversion Flex 4 2720 */ 2721 public function get displayObject():DisplayObject 2722 { 2723 return _displayObject; 2724 } 2725 2726 /** 2727 * @private 2728 */ 2729 protected function setDisplayObject(value:DisplayObject):void 2730 { 2731 if (_displayObject == value) 2732 return; 2733 2734 var oldValue:DisplayObject = _displayObject; 2735 2736 // If we owned the old display object and we have assigned a 3D matrix, 2737 // clear it from the display object so that we can set it in the new 2738 // display object. A Matrix3D object can't be used simultaneously with 2739 // more than one display object. 2740 if (oldValue && displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT) 2741 oldValue.transform.matrix3D = null; 2742 2743 _displayObject = value; 2744 dispatchPropertyChangeEvent("displayObject", oldValue, value); 2745 2746 // We need to apply the display object related properties. 2747 displayObjectChanged = true; 2748 invalidateProperties(); 2749 } 2750 2751 //-------------------------------------------------------------------------- 2752 // 2753 // Properties 2754 // 2755 //-------------------------------------------------------------------------- 2756 2757 //---------------------------------- 2758 // drawX 2759 //---------------------------------- 2760 2761 /** 2762 * The x position where the element should be drawn. 2763 * 2764 * @langversion 3.0 2765 * @playerversion Flash 10 2766 * @playerversion AIR 1.5 2767 * @productversion Flex 4 2768 */ 2769 protected function get drawX():Number 2770 { 2771 // If we don't share the display object, we will draw at 0,0 2772 // since the display object will be positioned at x,y 2773 if (displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT) 2774 return 0; 2775 2776 // Otherwise we draw at x,y since the display object will be 2777 // positioned at 0,0 2778 if (layoutFeatures != null && layoutFeatures.postLayoutTransformOffsets != null) 2779 return x + layoutFeatures.postLayoutTransformOffsets.x; 2780 2781 return x; 2782 } 2783 2784 //---------------------------------- 2785 // drawY 2786 //---------------------------------- 2787 2788 /** 2789 * The y position where the element should be drawn. 2790 * 2791 * @langversion 3.0 2792 * @playerversion Flash 10 2793 * @playerversion AIR 1.5 2794 * @productversion Flex 4 2795 */ 2796 protected function get drawY():Number 2797 { 2798 // If we don't share the display object, we will draw at 0,0 2799 // since the display object will be positioned at x,y 2800 if (displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT) 2801 return 0; 2802 2803 // Otherwise we draw at x,y since the display object will be 2804 // positioned at 0,0 2805 if (layoutFeatures != null && layoutFeatures.postLayoutTransformOffsets != null) 2806 return y + layoutFeatures.postLayoutTransformOffsets.y; 2807 2808 return y; 2809 } 2810 2811 //---------------------------------- 2812 // hasComplexLayoutMatrix 2813 //---------------------------------- 2814 2815 /** 2816 * Returns true if the GraphicElement has any non-translation (x,y) transform properties 2817 * 2818 * @langversion 3.0 2819 * @playerversion Flash 10 2820 * @playerversion AIR 1.5 2821 * @productversion Flex 4 2822 */ 2823 protected function get hasComplexLayoutMatrix():Boolean 2824 { 2825 return (layoutFeatures == null ? false : !MatrixUtil.isDeltaIdentity(layoutFeatures.layoutMatrix)); 2826 } 2827 2828 //---------------------------------- 2829 // includeInLayout 2830 //---------------------------------- 2831 2832 /** 2833 * @private 2834 * Storage for the includeInLayout property. 2835 */ 2836 private var _includeInLayout:Boolean = true; 2837 2838 [Inspectable(category="General", defaultValue="true")] 2839 2840 /** 2841 * Specifies whether this element is included in the layout of the parent. 2842 * 2843 * @default true 2844 * 2845 * @langversion 3.0 2846 * @playerversion Flash 10 2847 * @playerversion AIR 1.5 2848 * @productversion Flex 4 2849 */ 2850 public function get includeInLayout():Boolean 2851 { 2852 return _includeInLayout; 2853 } 2854 2855 /** 2856 * @private 2857 */ 2858 public function set includeInLayout(value:Boolean):void 2859 { 2860 if (_includeInLayout == value) 2861 return; 2862 2863 // Temporarily set includeInLayout to true so that 2864 // invalidating the parent doesn't return early. 2865 _includeInLayout = true; 2866 invalidateParentSizeAndDisplayList(); 2867 2868 _includeInLayout = value; 2869 } 2870 2871 //---------------------------------- 2872 // displayObjectSharingMode 2873 //---------------------------------- 2874 2875 private var _displayObjectSharingMode:String; 2876 2877 [Inspectable(category="General", enumeration="ownsUnsharedObject,ownsSharedObject,usesSharedObject")] 2878 2879 /** 2880 * @private 2881 */ 2882 public function set displayObjectSharingMode(value:String):void 2883 { 2884 if (value == _displayObjectSharingMode) 2885 return; 2886 2887 if (value != DisplayObjectSharingMode.USES_SHARED_OBJECT || 2888 _displayObjectSharingMode != DisplayObjectSharingMode.USES_SHARED_OBJECT) 2889 { 2890 // If the element was previously at the head of the shared sequence or 2891 // it is assigned to be at the head, make sure to reapply the 2892 // displayObject specific properties. 2893 displayObjectChanged = true; 2894 invalidateProperties(); 2895 } 2896 _displayObjectSharingMode = value; 2897 } 2898 2899 /** 2900 * @inheritDoc 2901 * 2902 * @langversion 3.0 2903 * @playerversion Flash 10 2904 * @playerversion AIR 1.5 2905 * @productversion Flex 4 2906 */ 2907 public function get displayObjectSharingMode():String 2908 { 2909 return _displayObjectSharingMode; 2910 } 2911 2912 //---------------------------------- 2913 // layoutDirection 2914 //---------------------------------- 2915 2916 private var _layoutDirection:String = null; 2917 2918 [Inspectable(category="General", enumeration="ltr,rtl")] 2919 2920 /** 2921 * @inheritDoc 2922 * 2923 * @langversion 3.0 2924 * @playerversion Flash 10 2925 * @playerversion AIR 1.5 2926 * @productversion Flex 4 2927 */ 2928 public function get layoutDirection():String 2929 { 2930 if (_layoutDirection != null) 2931 return _layoutDirection; 2932 2933 const parentElt:ILayoutDirectionElement = parent as ILayoutDirectionElement; 2934 return (parentElt) ? parentElt.layoutDirection : LayoutDirection.LTR; 2935 } 2936 2937 /** 2938 * @private 2939 */ 2940 public function set layoutDirection(value:String):void 2941 { 2942 if (_layoutDirection == value) 2943 return; 2944 2945 _layoutDirection = value; 2946 invalidateLayoutDirection(); 2947 } 2948 2949 /** 2950 * @inheritDoc 2951 * 2952 * @langversion 3.0 2953 * @playerversion Flash 10 2954 * @playerversion AIR 1.5 2955 * @productversion Flex 4 2956 */ 2957 public function invalidateLayoutDirection():void 2958 { 2959 const parentElt:ILayoutDirectionElement = parent as ILayoutDirectionElement; 2960 if (!parentElt) 2961 return; 2962 2963 // If this element's layoutDirection doesn't match its parent's, then 2964 // set the layoutFeatures.mirror flag. Similarly, if mirroring isn't 2965 // required, then clear the layoutFeatures.mirror flag. 2966 2967 const mirror:Boolean = (parentElt.layoutDirection != null && _layoutDirection != null) 2968 && (_layoutDirection != parentElt.layoutDirection); 2969 2970 if ((layoutFeatures) ? (mirror != layoutFeatures.mirror) : mirror) 2971 { 2972 if (layoutFeatures == null) 2973 allocateLayoutFeatures(); 2974 var previous:Boolean = needsDisplayObject; 2975 layoutFeatures.mirror = mirror; 2976 invalidateTransform(previous != needsDisplayObject); 2977 } 2978 } 2979 2980 //-------------------------------------------------------------------------- 2981 // 2982 // Methods 2983 // 2984 //-------------------------------------------------------------------------- 2985 2986 /** 2987 * Called automatically by the MXML compiler when the GraphicElement 2988 * is created using an MXML tag. 2989 * If you create the GraphicElement through ActionScript you must set the 2990 * <code>id</code> property manually. 2991 * 2992 * @param document The MXML document containing this GraphicElement (not used). 2993 * @param id The MXML id for this GraphicElement. 2994 * 2995 * @langversion 3.0 2996 * @playerversion Flash 10 2997 * @playerversion AIR 1.5 2998 * @productversion Flex 4 2999 */ 3000 public function initialized(document:Object, id:String):void 3001 { 3002 this.id = id; 3003 } 3004 3005 /** 3006 * Converts the point object from the object's (local) coordinates 3007 * to the Stage (global) coordinates. 3008 * 3009 * <p>This method allows you to convert any given x and y coordinates from 3010 * values that are relative to the origin (0,0) of a specific object 3011 * (local coordinates) to values that are relative to the origin 3012 * of the Stage (global coordinates).</p> 3013 * 3014 * <p>To use this method, first create an instance of the Point class. 3015 * The x and y values that you assign represent local coordinates 3016 * because they relate to the origin of the object.</p> 3017 * 3018 * <p>You then pass the Point instance that you created as the parameter 3019 * to the localToGlobal() method. The method returns a new Point object 3020 * with x and y values that relate to the origin of the Stage instead of 3021 * the origin of the object.</p> 3022 * 3023 * @param point The name or identifier of a point created with the Point 3024 * class, specifying the x and y coordinates as properties. 3025 * 3026 * @return A Point object with coordinates relative to the Stage. 3027 * 3028 * @see flash.display.DisplayObject#localToGlobal 3029 * 3030 * @langversion 3.0 3031 * @playerversion Flash 10 3032 * @playerversion AIR 1.5 3033 * @productversion Flex 4 3034 */ 3035 public function localToGlobal(point:Point):Point 3036 { 3037 // If there is not yet a displayObject or it's not parented, just 3038 // return its local position 3039 if (!displayObject || !displayObject.parent) 3040 return new Point(x, y); 3041 3042 var returnVal:Point = displayObject.localToGlobal(point); 3043 3044 if (!needsDisplayObject) 3045 { 3046 // If we're sharing the displayObject, add in our offset 3047 returnVal.x += drawX; 3048 returnVal.y += drawY; 3049 } 3050 3051 return returnVal; 3052 } 3053 3054 /** 3055 * @inheritDoc 3056 * 3057 * @langversion 3.0 3058 * @playerversion Flash 10 3059 * @playerversion AIR 1.5 3060 * @productversion Flex 4 3061 */ 3062 public function createDisplayObject():DisplayObject 3063 { 3064 setDisplayObject(new InvalidatingSprite()); 3065 return displayObject; 3066 } 3067 3068 /** 3069 * True if the element requires an exclusive DisplayObject. 3070 * 3071 * Developers don't usually call this method directly, but override it in 3072 * their subclasses to indicate that an exclusive DisplayObject is needed. 3073 * 3074 * Usually a subclass needs a DisplayObject when it has to set its properties. 3075 * 3076 * Some examples of such DisplayObject properties are <code>filters</code>, 3077 * <code>blendMode</code>, <code>mask</code>, 3078 * <code>rotation</code>, <code>alpha</code>. 3079 * 3080 * @return Returns true when the element requires an exclusive DisplayObject. 3081 * 3082 * @langversion 3.0 3083 * @playerversion Flash 10 3084 * @playerversion AIR 1.5 3085 * @productversion Flex 4 3086 */ 3087 protected function get needsDisplayObject():Boolean 3088 { 3089 var result:Boolean = (alwaysCreateDisplayObject || 3090 (_filters && _filters.length > 0) || 3091 (_blendMode != BlendMode.NORMAL && _blendMode != "auto") || _mask || 3092 (layoutFeatures != null && (layoutFeatures.layoutScaleX != 1 || layoutFeatures.layoutScaleY != 1 || layoutFeatures.layoutScaleZ != 1 || 3093 layoutFeatures.layoutRotationX != 0 || layoutFeatures.layoutRotationY != 0 || layoutFeatures.layoutRotationZ != 0 || 3094 layoutFeatures.layoutZ != 0 || layoutFeatures.mirror)) || 3095 _colorTransform != null || 3096 _effectiveAlpha != 1); 3097 3098 if (layoutFeatures != null && layoutFeatures.postLayoutTransformOffsets != null) 3099 { 3100 var o:TransformOffsets = layoutFeatures.postLayoutTransformOffsets; 3101 result = result || (o.scaleX != 1 || o.scaleY != 1 || o.scaleZ != 1 || 3102 o.rotationX != 0 || o.rotationY != 0 || o.rotationZ != 0 || o.z != 0); 3103 } 3104 3105 return result; 3106 } 3107 3108 /** 3109 * @inheritDoc 3110 * 3111 * @langversion 3.0 3112 * @playerversion Flash 10 3113 * @playerversion AIR 1.5 3114 * @productversion Flex 4 3115 */ 3116 public function setSharedDisplayObject(sharedDisplayObject:DisplayObject):Boolean 3117 { 3118 if (!(sharedDisplayObject is Sprite) || _alwaysCreateDisplayObject || needsDisplayObject) 3119 return false; 3120 setDisplayObject(sharedDisplayObject); 3121 return true; 3122 } 3123 3124 /** 3125 * @inheritDoc 3126 * 3127 * @langversion 3.0 3128 * @playerversion Flash 10 3129 * @playerversion AIR 1.5 3130 * @productversion Flex 4 3131 */ 3132 public function canShareWithPrevious(element:IGraphicElement):Boolean 3133 { 3134 // No need to check _alwaysCreateDisplayObject or needsDisplayObject, 3135 // as those will be checked in setSharedDisplayObject 3136 return element is GraphicElement; 3137 } 3138 3139 /** 3140 * @inheritDoc 3141 * 3142 * @langversion 3.0 3143 * @playerversion Flash 10 3144 * @playerversion AIR 1.5 3145 * @productversion Flex 4 3146 */ 3147 public function canShareWithNext(element:IGraphicElement):Boolean 3148 { 3149 return element is GraphicElement && !_alwaysCreateDisplayObject && !needsDisplayObject; 3150 } 3151 3152 /** 3153 * The actual DisplayObject that is drawn into by the GraphicElement. Typically this is 3154 * equivalent to the <code>displayObject</code> property. Subclasses should perform drawing commands on 3155 * this property instead of on <code>displayObject</code>. 3156 * 3157 * @langversion 3.0 3158 * @playerversion Flash 10 3159 * @playerversion AIR 1.5 3160 * @productversion Flex 4 3161 */ 3162 protected function get drawnDisplayObject():DisplayObject 3163 { 3164 // _drawnDisplayObject is non-null if we needed to create a mask 3165 return _drawnDisplayObject ? _drawnDisplayObject : displayObject; 3166 } 3167 3168 /** 3169 * Returns a bitmap snapshot of the GraphicElement. 3170 * The bitmap contains all transformations and is reduced 3171 * to fit the visual bounds of the object. 3172 * 3173 * @param transparent Whether or not the bitmap image supports per-pixel transparency. 3174 * The default value is true (transparent). To create a fully transparent bitmap, set the value of the 3175 * transparent parameter to true and the value of the fillColor parameter to 0x00000000 (or to 0). 3176 * Setting the transparent property to false can result in minor improvements in rendering performance. 3177 * 3178 * @param fillColor A 32-bit ARGB color value that you use to fill the bitmap image area. 3179 * The default value is 0xFFFFFFFF (solid white). 3180 * 3181 * @param useLocalSpace Whether or not the bitmap shows the GraphicElement in the local or global 3182 * coordinate space. If true, then the snapshot is in the local space. The default value is true. 3183 * 3184 * @param clipRect A Rectangle object that defines the area of the source object to draw. 3185 * If you do not supply this value, no clipping occurs and the entire source object is drawn. 3186 * The clipRect should be defined in the coordinate space specified by useLocalSpace 3187 * 3188 * @return A bitmap snapshot of the GraphicElement or null if the input element has no visible bounds. 3189 * 3190 * 3191 * @langversion 3.0 3192 * @playerversion Flash 10 3193 * @playerversion AIR 1.5 3194 * @productversion Flex 4 3195 */ 3196 mx_internal function captureBitmapData(transparent:Boolean = true, fillColor:uint = 0xFFFFFFFF, useLocalSpace:Boolean = true, clipRect:Rectangle = null):BitmapData 3197 { 3198 if (!layoutFeatures || !layoutFeatures.is3D) 3199 { 3200 var restoreDisplayObject:Boolean = false; 3201 var oldDisplayObject:DisplayObject; 3202 3203 if (!displayObject || displayObjectSharingMode != DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT) 3204 { 3205 restoreDisplayObject = true; 3206 oldDisplayObject = displayObject; 3207 setDisplayObject(new InvalidatingSprite()); 3208 if (parent is UIComponent) 3209 UIComponent(parent).$addChild(displayObject); 3210 else 3211 parent.addChild(displayObject); 3212 invalidateDisplayList(); 3213 validateDisplayList(); 3214 } 3215 3216 var topLevel:Sprite = Sprite(IUIComponent(parent).systemManager.getSandboxRoot()); 3217 var rectBounds:Rectangle = useLocalSpace ? 3218 new Rectangle(getLayoutBoundsX(), getLayoutBoundsY(), getLayoutBoundsWidth(), getLayoutBoundsHeight()) : 3219 displayObject.getBounds(topLevel); 3220 3221 if (rectBounds.width == 0 || rectBounds.height == 0) 3222 return null; 3223 3224 var bitmapData:BitmapData = new BitmapData(Math.ceil(rectBounds.width), Math.ceil(rectBounds.height), transparent, fillColor); 3225 3226 // Can't use target's concatenatedMatrix, as it is sometimes wrong 3227 var m:Matrix = useLocalSpace ? 3228 displayObject.transform.matrix : 3229 MatrixUtil.getConcatenatedMatrix(displayObject, null); 3230 3231 if (m) 3232 m.translate(-rectBounds.x, -rectBounds.y); 3233 3234 bitmapData.draw(displayObject, m, null, null, clipRect); 3235 3236 if (restoreDisplayObject) 3237 { 3238 if (parent is UIComponent) 3239 UIComponent(parent).$removeChild(displayObject); 3240 else 3241 parent.removeChild(displayObject); 3242 setDisplayObject(oldDisplayObject); 3243 } 3244 return bitmapData; 3245 3246 } 3247 else 3248 { 3249 return get3DSnapshot(transparent, fillColor, useLocalSpace); 3250 } 3251 } 3252 3253 /** 3254 * @private 3255 * Returns a bitmap snapshot of a 3D transformed displayObject. Since BitmapData.draw ignores 3256 * the transform matrix of its target when it draws, we need to parent the target in a temporary 3257 * sprite and call BitmapData.draw on that temp sprite. We can't take a bitmap snapshot of the 3258 * real parent because it might have other children. 3259 */ 3260 private function get3DSnapshot(transparent:Boolean = true, fillColor:uint = 0xFFFFFFFF, useLocalSpace:Boolean = true):BitmapData 3261 { 3262 var topLevel:Sprite = Sprite(IUIComponent(parent).systemManager); 3263 var dispObjParent:DisplayObjectContainer = displayObject.parent; 3264 var drawSprite:Sprite = new Sprite(); 3265 3266 // Get the visual bounds of the target in both local and global coordinates 3267 var topLevelRect:Rectangle = displayObject.getBounds(topLevel); 3268 var displayObjectRect:Rectangle = displayObject.getBounds(dispObjParent); 3269 3270 // Keep a reference to the original 3D matrix. We will restore this later. 3271 var oldMat3D:Matrix3D = displayObject.transform.matrix3D.clone(); 3272 3273 // Get the concatenated 3D matrix which we will use to position the target when we reparent it 3274 var globalMat3D:Matrix3D = displayObject.transform.getRelativeMatrix3D(topLevel); 3275 var newMat3D:Matrix3D = oldMat3D.clone(); 3276 3277 3278 // Remove the target from its current parent, making sure to store the child index 3279 var displayObjectIndex:int = parent.getChildIndex(displayObject); 3280 if (parent is UIComponent) 3281 UIComponent(parent).$removeChild(displayObject); 3282 else 3283 parent.removeChild(displayObject); 3284 3285 // Parent the target to the drawSprite and then attach the drawSprite to the stage 3286 topLevel.addChild(drawSprite); 3287 drawSprite.addChild(displayObject); 3288 3289 // Assign the globally translated matrix to the target 3290 if (useLocalSpace) 3291 { 3292 newMat3D.position = globalMat3D.position; 3293 displayObject.transform.matrix3D = newMat3D; 3294 } 3295 else 3296 { 3297 displayObject.transform.matrix3D = globalMat3D; 3298 } 3299 // Translate the bitmap so that the left-top bounds ends up at (0,0) 3300 var m:Matrix = new Matrix(); 3301 m.translate(-topLevelRect.left, - topLevelRect.top); 3302 3303 // Draw to the bitmapData 3304 var snapshot:BitmapData = new BitmapData( topLevelRect.width, topLevelRect.height, transparent, fillColor); 3305 snapshot.draw(drawSprite, m, null, null, null, true); 3306 3307 // Remove target from temporary sprite and remove temp sprite from stage 3308 drawSprite.removeChild(displayObject); 3309 topLevel.removeChild(drawSprite); 3310 3311 // Reattach the target to its original parent at its original child position 3312 if (parent is UIComponent) 3313 UIComponent(parent).$addChildAt(displayObject, displayObjectIndex); 3314 else 3315 parent.addChildAt(displayObject, displayObjectIndex); 3316 3317 // Restore the original 3D matrix 3318 displayObject.transform.matrix3D = oldMat3D; 3319 3320 return snapshot; 3321 } 3322 3323 /** 3324 * @private 3325 */ 3326 protected function layer_PropertyChange(event:PropertyChangeEvent):void 3327 { 3328 switch (event.property) 3329 { 3330 case "effectiveVisibility": 3331 { 3332 var newValue:Boolean = (event.newValue && _visible); 3333 3334 if (newValue != _effectiveVisibility) 3335 { 3336 _effectiveVisibility = newValue; 3337 visibleChanged = true; 3338 invalidateProperties(); 3339 } 3340 break; 3341 } 3342 case "effectiveAlpha": 3343 { 3344 var newAlpha:Number = Number(event.newValue) * _alpha; 3345 if (newAlpha != _effectiveAlpha) 3346 { 3347 _effectiveAlpha = newAlpha; 3348 alphaChanged = true; 3349 3350 var mxTransform:mx.geom.Transform = _transform as mx.geom.Transform; 3351 if (mxTransform) 3352 mxTransform.applyColorTransformAlpha = false; 3353 3354 invalidateDisplayObjectSharing(); 3355 invalidateProperties(); 3356 } 3357 break; 3358 } 3359 } 3360 } 3361 3362 /** 3363 * Dispatches a propertyChange event. 3364 * 3365 * @param prop The property that changed. 3366 * 3367 * @param oldValue The previous value of the property. 3368 * 3369 * @param value The new value of the property. 3370 * 3371 * @langversion 3.0 3372 * @playerversion Flash 10 3373 * @playerversion AIR 1.5 3374 * @productversion Flex 4 3375 */ 3376 mx_internal function dispatchPropertyChangeEvent(prop:String, oldValue:*, 3377 value:*):void 3378 { 3379 if (hasEventListener("propertyChange")) 3380 dispatchEvent(PropertyChangeEvent.createUpdateEvent( 3381 this, prop, oldValue, value)); 3382 3383 } 3384 3385 /** 3386 * Utility method that notifies the host that this element has changed and needs 3387 * its layer to be updated. 3388 * 3389 * @langversion 3.0 3390 * @playerversion Flash 10 3391 * @playerversion AIR 1.5 3392 * @productversion Flex 4 3393 */ 3394 protected function invalidateDisplayObjectSharing():void 3395 { 3396 if (parent) 3397 IGraphicElementContainer(parent).invalidateGraphicElementSharing(this); 3398 } 3399 3400 /** 3401 * Calling this method results in a call to the elements's 3402 * <code>validateProperties()</code> method 3403 * before the display list is rendered. 3404 * 3405 * <p>Subclasses should do their work in 3406 * <code>commitProperties()</code>.</p> 3407 * 3408 * @langversion 3.0 3409 * @playerversion Flash 10 3410 * @playerversion AIR 1.5 3411 * @productversion Flex 4 3412 */ 3413 public function invalidateProperties():void 3414 { 3415 if (invalidatePropertiesFlag) 3416 return; 3417 invalidatePropertiesFlag = true; 3418 3419 if (parent) 3420 IGraphicElementContainer(parent).invalidateGraphicElementProperties(this); 3421 } 3422 3423 /** 3424 * Calling this method results in a call to the elements's 3425 * <code>validateSize()</code> method 3426 * before the display list is rendered. 3427 * 3428 * <p>Subclasses should override and do their measurement in 3429 * <code>measure()</code>. 3430 * By default when <code>explicitWidth</code> and <code>explicitHeight</code> 3431 * are set, <code>measure()</code> will not be called. To override this 3432 * default behavior subclasses should override <code>skipMeasure()</code>.</p> 3433 * 3434 * @langversion 3.0 3435 * @playerversion Flash 10 3436 * @playerversion AIR 1.5 3437 * @productversion Flex 4 3438 */ 3439 public function invalidateSize():void 3440 { 3441 if (invalidateSizeFlag) 3442 return; 3443 invalidateSizeFlag = true; 3444 3445 if (parent) 3446 IGraphicElementContainer(parent).invalidateGraphicElementSize(this); 3447 } 3448 3449 /** 3450 * Helper method to invalidate parent size and display list if 3451 * this object affects its layout (includeInLayout is true). 3452 * 3453 * @langversion 3.0 3454 * @playerversion Flash 10 3455 * @playerversion AIR 1.5 3456 * @productversion Flex 4 3457 */ 3458 protected function invalidateParentSizeAndDisplayList():void 3459 { 3460 if (!includeInLayout) 3461 return; 3462 3463 // We want to invalidate both the parent size and parent display list. 3464 if (parent && parent is IInvalidating) 3465 { 3466 IInvalidating(parent).invalidateSize(); 3467 IInvalidating(parent).invalidateDisplayList(); 3468 } 3469 } 3470 3471 /** 3472 * Calling this method results in a call to the elements's 3473 * <code>validateDisplayList()</code> method 3474 * before the display list is rendered. 3475 * 3476 * <p>Subclasses should override and do their work in 3477 * <code>updateDisplayList()</code>.</p> 3478 * 3479 * @langversion 3.0 3480 * @playerversion Flash 10 3481 * @playerversion AIR 1.5 3482 * @productversion Flex 4 3483 */ 3484 public function invalidateDisplayList():void 3485 { 3486 if (invalidateDisplayListFlag) 3487 return; 3488 invalidateDisplayListFlag = true; 3489 3490 // The IGraphicElementContainer will take care of redrawing all graphic elements that 3491 // share the display object with this element. 3492 if (parent) 3493 IGraphicElementContainer(parent).invalidateGraphicElementDisplayList(this); 3494 } 3495 3496 /** 3497 * Validates and updates the properties and layout of this object 3498 * by immediately calling <code>validateProperties()</code>, 3499 * <code>validateSize()</code>, and <code>validateDisplayList()</code>, 3500 * if necessary. 3501 * 3502 * @langversion 3.0 3503 * @playerversion Flash 10 3504 * @playerversion AIR 1.5 3505 * @productversion Flex 4 3506 */ 3507 public function validateNow():void 3508 { 3509 if (parent) 3510 { 3511 UIComponentGlobals.layoutManager.validateClient( 3512 ILayoutManagerClient(parent)); 3513 } 3514 } 3515 3516 /** 3517 * Used by layout logic to validate the properties of a component 3518 * by calling the <code>commitProperties()</code> method. 3519 * In general, subclasses should 3520 * override the <code>commitProperties()</code> method and not this method. 3521 * 3522 * @langversion 3.0 3523 * @playerversion Flash 10 3524 * @playerversion AIR 1.5 3525 * @productversion Flex 4 3526 */ 3527 public function validateProperties():void 3528 { 3529 if (!invalidatePropertiesFlag) 3530 return; 3531 commitProperties(); 3532 invalidatePropertiesFlag = false; 3533 3534 // If we aren't doing any more invalidation, send out an UpdateComplete event 3535 if (!invalidatePropertiesFlag && !invalidateSizeFlag && !invalidateDisplayListFlag) 3536 dispatchUpdateComplete(); 3537 } 3538 3539 /** 3540 * Processes the properties set on the element. 3541 * This is an advanced method that you might override 3542 * when creating a subclass. 3543 * 3544 * <p>You do not call this method directly. 3545 * Flex calls the <code>commitProperties()</code> method when you 3546 * use the <code>addElement()</code> method to add an element to an 3547 * <code>IGraphicElementContainer</code> container such as Group, 3548 * or when you call the <code>invalidateProperties()</code> method of the element. 3549 * Calls to the <code>commitProperties()</code> method occur before calls to the 3550 * <code>measure()</code> method. This lets you set property values that might 3551 * be used by the <code>measure()</code> method.</p> 3552 * 3553 * <p>Some elements have properties that 3554 * interact with each other. 3555 * It is often best at startup time to process all of these 3556 * properties at one time to avoid duplicating work.</p> 3557 * 3558 * @langversion 3.0 3559 * @playerversion Flash 10 3560 * @playerversion AIR 1.5 3561 * @productversion Flex 4 3562 */ 3563 protected function commitProperties():void 3564 { 3565 //trace("GraphicElement.commitProperties displayObject",displayObject,"this",this); 3566 var updateTransform:Boolean = false; 3567 var mxTransform:mx.geom.Transform; 3568 3569 // If we are the first in the sequence, setup the displayObject properties 3570 if (displayObjectSharingMode != DisplayObjectSharingMode.USES_SHARED_OBJECT && displayObject) 3571 { 3572 if (colorTransformChanged || displayObjectChanged) 3573 { 3574 colorTransformChanged = false; 3575 if (_colorTransform) 3576 displayObject.transform.colorTransform = _colorTransform; 3577 } 3578 3579 if (alphaChanged || displayObjectChanged) 3580 { 3581 alphaChanged = false; 3582 3583 mxTransform = _transform as mx.geom.Transform; 3584 if (!mxTransform || !mxTransform.applyColorTransformAlpha) 3585 displayObject.alpha = _effectiveAlpha; 3586 } 3587 3588 if (blendModeChanged || displayObjectChanged) 3589 { 3590 blendModeChanged = false; 3591 3592 // Figure out the correct value to push down 3593 // to the displayObject's blendMode 3594 if (_blendMode == "auto") 3595 { 3596 if (alpha == 0 || alpha == 1) 3597 displayObject.blendMode = BlendMode.NORMAL; 3598 else 3599 displayObject.blendMode = BlendMode.LAYER; 3600 } 3601 3602 else if (!isAIMBlendMode(_blendMode)) 3603 { 3604 displayObject.blendMode = _blendMode; 3605 } 3606 3607 // The blendMode is neither a native value, 3608 // or the 'auto' value so lets set blendMode 3609 // to normal. 3610 else 3611 { 3612 displayObject.blendMode = "normal"; 3613 } 3614 3615 if (blendShaderChanged) 3616 { 3617 // The graphic element's blendMode was set to a non-Flash 3618 // blendMode. We mimic the look by instantiating the 3619 // appropriate shader class and setting the blendShader 3620 // property on the displayObject. 3621 blendShaderChanged = false; 3622 3623 switch(_blendMode) 3624 { 3625 case "color": 3626 { 3627 displayObject.blendShader = new ColorShader(); 3628 break; 3629 } 3630 case "colordodge": 3631 { 3632 displayObject.blendShader = new ColorDodgeShader(); 3633 break; 3634 } 3635 case "colorburn": 3636 { 3637 displayObject.blendShader = new ColorBurnShader(); 3638 break; 3639 } 3640 case "exclusion": 3641 { 3642 displayObject.blendShader = new ExclusionShader(); 3643 break; 3644 } 3645 case "hue": 3646 { 3647 displayObject.blendShader = new HueShader(); 3648 break; 3649 } 3650 case "luminosity": 3651 { 3652 displayObject.blendShader = new LuminosityShader(); 3653 break; 3654 } 3655 case "saturation": 3656 { 3657 displayObject.blendShader = new SaturationShader(); 3658 break; 3659 } 3660 case "softlight": 3661 { 3662 displayObject.blendShader = new SoftLightShader(); 3663 break; 3664 } 3665 } 3666 } 3667 } 3668 3669 if (filtersChanged || displayObjectChanged) 3670 { 3671 filtersChanged = false; 3672 3673 // there's a flash player bug...even setting filters to null here 3674 // causes memory to skyrocket 3675 if (filtersChanged || _clonedFilters) 3676 displayObject.filters = _clonedFilters; 3677 } 3678 3679 if (maskChanged || displayObjectChanged) 3680 { 3681 maskChanged = false; 3682 3683 if (_mask) 3684 { 3685 // If the mask is not parented, then we need to parent it. 3686 // Since a mask can not be a child of the maskee, 3687 // we make the mask and maskee siblings. We create a new maskee 3688 // called _drawnDisplayObject. Then we attach both the mask 3689 // and maskee to displayObject. 3690 if (!_mask.parent) 3691 { 3692 Sprite(displayObject).addChild(_mask); 3693 3694 MaskUtil.applyMask(_mask, parent); 3695 3696 if (!_drawnDisplayObject) 3697 { 3698 // Clear the original displayObject because it might have previously 3699 // drawn the shape. 3700 if (displayObject is Sprite) 3701 Sprite(displayObject).graphics.clear(); 3702 else if (displayObject is Shape) 3703 Shape(displayObject).graphics.clear(); 3704 3705 // Create a new target for the drawing commands 3706 _drawnDisplayObject = new InvalidatingSprite(); 3707 Sprite(displayObject).addChild(_drawnDisplayObject); 3708 } 3709 } 3710 3711 drawnDisplayObject.mask = _mask; 3712 } 3713 } 3714 3715 if (luminositySettingsChanged) 3716 { 3717 luminositySettingsChanged = false; 3718 3719 MaskUtil.applyLuminositySettings( 3720 _mask, _maskType, _luminosityInvert, _luminosityClip); 3721 } 3722 3723 if (maskTypeChanged || displayObjectChanged) 3724 { 3725 maskTypeChanged = false; 3726 MaskUtil.applyMaskType( 3727 _mask, _maskType, _luminosityInvert, _luminosityClip, 3728 drawnDisplayObject); 3729 } 3730 3731 // If we don't share the DisplayObject, set the property directly. 3732 // If displayObject has changed and we're sharing, then ensure 3733 // the visible property is set to true. 3734 if (displayObjectChanged) 3735 displayObject.visible = (displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT) ? _effectiveVisibility : true; 3736 3737 updateTransform = true; 3738 displayObjectChanged = false; 3739 } 3740 3741 if (visibleChanged) 3742 { 3743 visibleChanged = false; 3744 3745 // If we don't share the DisplayObject, set the property directly, 3746 // otherwise redraw. 3747 if (displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT) 3748 { 3749 displayObject.visible = _effectiveVisibility; 3750 } 3751 else 3752 invalidateDisplayList(); 3753 } 3754 3755 if ((layoutFeatures == null || layoutFeatures.updatePending) || 3756 updateTransform) 3757 { 3758 applyComputedTransform(); 3759 } 3760 } 3761 3762 /** 3763 * @inheritDoc 3764 * 3765 * @langversion 3.0 3766 * @playerversion Flash 10 3767 * @playerversion AIR 1.5 3768 * @productversion Flex 4 3769 */ 3770 public function validateSize():void 3771 { 3772 if (!invalidateSizeFlag) 3773 return; 3774 invalidateSizeFlag = false; 3775 3776 var sizeChanging:Boolean = measureSizes(); 3777 3778 if (!sizeChanging || !includeInLayout) 3779 { 3780 // If we aren't doing any more invalidation, send out an UpdateComplete event 3781 if (!invalidatePropertiesFlag && !invalidateSizeFlag && !invalidateDisplayListFlag) 3782 dispatchUpdateComplete(); 3783 return; 3784 } 3785 3786 // Our size has changed, parent has to resize and run layout code 3787 invalidateParentSizeAndDisplayList(); 3788 } 3789 3790 /** 3791 * Determines if the call to the <code>measure()</code> method can be skipped. 3792 * 3793 * @return Returns <code>true</code> when the <code>measureSizes()</code> method can skip the call to 3794 * the <code>measure()</code> method. For example this is usually <code>true</code> when both the <code>explicitWidth</code> and 3795 * <code>explicitHeight</code> properties are set. For paths, this is <code>true</code> when the bounds of the path 3796 * have not changed. 3797 * 3798 * @langversion 3.0 3799 * @playerversion Flash 10 3800 * @playerversion AIR 1.5 3801 * @productversion Flex 4 3802 */ 3803 protected function canSkipMeasurement():Boolean 3804 { 3805 return !isNaN(explicitWidth) && !isNaN(explicitHeight); 3806 } 3807 3808 /** 3809 * @private 3810 */ 3811 private function measureSizes():Boolean 3812 { 3813 var oldWidth:Number = preferredWidthPreTransform(); 3814 var oldHeight:Number = preferredHeightPreTransform(); 3815 var oldX:Number = measuredX; 3816 var oldY:Number = measuredY; 3817 3818 if (!canSkipMeasurement()) 3819 measure(); 3820 3821 if (!isNaN(explicitMinWidth) && measuredWidth < explicitMinWidth) 3822 measuredWidth = explicitMinWidth; 3823 3824 if (!isNaN(explicitMaxWidth) && measuredWidth > explicitMaxWidth) 3825 measuredWidth = explicitMaxWidth; 3826 3827 if (!isNaN(explicitMinHeight) && measuredHeight < explicitMinHeight) 3828 measuredHeight = explicitMinHeight; 3829 3830 if (!isNaN(explicitMaxHeight) && measuredHeight > explicitMaxHeight) 3831 measuredHeight = explicitMaxHeight; 3832 3833 // Did measure() have effect on preferred size? 3834 if (oldWidth != preferredWidthPreTransform() || 3835 oldHeight != preferredHeightPreTransform() || 3836 oldX != measuredX || 3837 oldY != measuredY) 3838 { 3839 // Preferred size has changed, layout will be affected. 3840 return true; 3841 } 3842 3843 return false; 3844 } 3845 3846 /** 3847 * Calculates the default size of the element. This is an advanced 3848 * method that you might override when creating a subclass of GraphicElement. 3849 * 3850 * <p>You do not call this method directly. Flex calls the 3851 * <code>measure()</code> method when the element is added to an 3852 * <code>IGraphicElementContainer</code> container such as Group 3853 * using the <code>addElement()</code> method, and when the element's 3854 * <code>invalidateSize()</code> method is called. </p> 3855 * 3856 * <p>By default you set both explicit height and explicit width of an element, 3857 * Flex does not call the <code>measure()</code> method, 3858 * even if you explicitly call the <code>invalidateSize()</code> method. 3859 * To override this behavior, override <code>skipMeasure()</code> method.</p> 3860 * 3861 * <p>In your override of this method, you must set the 3862 * <code>measuredWidth</code> and <code>measuredHeight</code> properties 3863 * to define the default size. 3864 * You can optionally set the <code>measuredX</code> and 3865 * <code>measuredY</code> properties to define the default measured bounds 3866 * top-left corner relative to the origin of the element.</p> 3867 * 3868 * <p>The conceptual point of <code>measure()</code> is for the element to 3869 * provide its own natural or intrinsic bounds as a default. Therefore, the 3870 * <code>measuredWidth</code> and <code>measuredHeight</code> properties 3871 * should be determined by factors such as:</p> 3872 * <ul> 3873 * <li>The amount of text the component needs to display.</li> 3874 * <li>The size of a JPEG image that the component displays.</li> 3875 * </ul> 3876 * 3877 * <p>In some cases, there is no intrinsic way to determine default values. 3878 * For example, a simple GreenCircle element might simply set 3879 * measuredWidth = 100 and measuredHeight = 100 in its <code>measure()</code> method to 3880 * provide a reasonable default size. In other cases, such as a TextArea, 3881 * an appropriate computation (such as finding the right width and height 3882 * that would just display all the text and have the aspect ratio of a Golden Rectangle) 3883 * might be too time-consuming to be worthwhile.</p> 3884 * 3885 * <p>The default implementation of <code>measure()</code> 3886 * sets the values of the <code>measuredWidth</code>, <code>measuredHeight</code>, 3887 * <code>measuredX</code>, and <code>measuredY</code> properties 3888 * to <code>0</code>.</p> 3889 * 3890 * @langversion 3.0 3891 * @playerversion Flash 10 3892 * @playerversion AIR 1.5 3893 * @productversion Flex 4 3894 */ 3895 protected function measure():void 3896 { 3897 measuredWidth = 0; 3898 measuredHeight = 0; 3899 measuredX = 0; 3900 measuredY = 0; 3901 } 3902 3903 /** 3904 * @inheritDoc 3905 * 3906 * @langversion 3.0 3907 * @playerversion Flash 10 3908 * @playerversion AIR 1.5 3909 * @productversion Flex 4 3910 */ 3911 public function validateDisplayList():void 3912 { 3913 // Don't check the invalidateDisplayListFlag for early return, the IGraphicElementContainer takes care to 3914 // call validateDisplayList() only for elements that need to redraw. 3915 // Note that even when invalidateDisplayListFlag is false for a particular element, 3916 // the IGraphicElementContainer may still call it to redraw if it shares a display object with another 3917 // element that is redrawing. 3918 // if (!invalidateDisplayListFlag) 3919 // return; 3920 3921 var wasInvalid:Boolean = invalidateDisplayListFlag; 3922 invalidateDisplayListFlag = false; 3923 3924 // we commit our transform in two places. First, during commit properties, because our size depends on it, 3925 // and our parent will most likely take it into account during layout. Secondly, here, because our parent will likely 3926 // change our xform as a result of layout, and we need to commit it before we end up on screen. 3927 if (layoutFeatures == null || layoutFeatures.updatePending) 3928 { 3929 applyComputedTransform(); 3930 } 3931 3932 // If we are the first in the sequence, clear the graphics: 3933 if (displayObjectSharingMode != DisplayObjectSharingMode.USES_SHARED_OBJECT) 3934 { 3935 if (drawnDisplayObject is Sprite) 3936 Sprite(drawnDisplayObject).graphics.clear(); 3937 // TODO (rfrishbe): We don't really support shapes, but we should 3938 //else if (drawnDisplayObject is Shape) 3939 //Shape(drawnDisplayObject).graphics.clear(); 3940 } 3941 3942 doUpdateDisplayList(); 3943 3944 // If we aren't doing any more invalidation, send out an UpdateComplete event 3945 if (!invalidatePropertiesFlag && !invalidateSizeFlag && !invalidateDisplayListFlag && wasInvalid) 3946 dispatchUpdateComplete(); 3947 3948 // LAYOUT_DEBUG 3949 //LayoutManager.debugHelper.addElement(ILayoutElement(this)); 3950 } 3951 3952 /** 3953 * @private 3954 */ 3955 mx_internal function doUpdateDisplayList():void 3956 { 3957 if (_effectiveVisibility || displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT) 3958 updateDisplayList(_width, _height); 3959 } 3960 3961 /** 3962 * Draws the element and/or sizes and positions its content. 3963 * This is an advanced method that you might override 3964 * when creating a subclass of GraphicElement. 3965 * 3966 * <p>You do not call this method directly. Flex calls the 3967 * <code>updateDisplayList()</code> method when the component is added 3968 * to an <code>IGraphicElementContainer</code> container such as Group 3969 * using the <code>addElement()</code> method, and when the element's 3970 * <code>invalidateDisplayList()</code> method is called. </p> 3971 * 3972 * <p>This method is where you would do programmatic drawing 3973 * using methods on the elements's displayObject 3974 * such as <code>graphics.drawRect()</code>.</p> 3975 * 3976 * @param unscaledWidth Specifies the width of the component, in pixels, 3977 * in the component's coordinates, regardless of the value of the 3978 * <code>scaleX</code> property of the component. 3979 3980 * @param unscaledHeight Specifies the height of the component, in pixels, 3981 * in the component's coordinates, regardless of the value of the 3982 * <code>scaleY</code> property of the component. 3983 * 3984 * @langversion 3.0 3985 * @playerversion Flash 10 3986 * @playerversion AIR 1.5 3987 * @productversion Flex 4 3988 */ 3989 protected function updateDisplayList(unscaledWidth:Number, 3990 unscaledHeight:Number):void 3991 { 3992 } 3993 3994 /** 3995 * @private 3996 * Helper function to dispatch the UpdateComplete event 3997 */ 3998 private function dispatchUpdateComplete():void 3999 { 4000 if (hasEventListener(FlexEvent.UPDATE_COMPLETE)) 4001 dispatchEvent(new FlexEvent(FlexEvent.UPDATE_COMPLETE)); 4002 } 4003 4004 //-------------------------------------------------------------------------- 4005 // 4006 // Methods: ILayoutElement 4007 // 4008 //-------------------------------------------------------------------------- 4009 4010 /** 4011 * @inheritDoc 4012 * 4013 * @langversion 3.0 4014 * @playerversion Flash 10 4015 * @playerversion AIR 1.5 4016 * @productversion Flex 4 4017 */ 4018 public function getMaxBoundsWidth(postLayoutTransform:Boolean = true):Number 4019 { 4020 return transformWidthForLayout(maxWidth, maxHeight, postLayoutTransform); 4021 } 4022 4023 /** 4024 * @inheritDoc 4025 * 4026 * @langversion 3.0 4027 * @playerversion Flash 10 4028 * @playerversion AIR 1.5 4029 * @productversion Flex 4 4030 */ 4031 public function getMaxBoundsHeight(postLayoutTransform:Boolean = true):Number 4032 { 4033 return transformHeightForLayout(maxWidth, maxHeight, postLayoutTransform); 4034 } 4035 4036 /** 4037 * @inheritDoc 4038 * 4039 * @langversion 3.0 4040 * @playerversion Flash 10 4041 * @playerversion AIR 1.5 4042 * @productversion Flex 4 4043 */ 4044 public function getMinBoundsWidth(postLayoutTransform:Boolean = true):Number 4045 { 4046 return transformWidthForLayout(minWidth, minHeight, postLayoutTransform); 4047 } 4048 4049 /** 4050 * @inheritDoc 4051 * 4052 * @langversion 3.0 4053 * @playerversion Flash 10 4054 * @playerversion AIR 1.5 4055 * @productversion Flex 4 4056 */ 4057 public function getMinBoundsHeight(postLayoutTransform:Boolean = true):Number 4058 { 4059 return transformHeightForLayout(minWidth, minHeight, postLayoutTransform); 4060 } 4061 4062 /** 4063 * @inheritDoc 4064 * 4065 * @langversion 3.0 4066 * @playerversion Flash 10 4067 * @playerversion AIR 1.5 4068 * @productversion Flex 4 4069 */ 4070 public function getPreferredBoundsWidth(postLayoutTransform:Boolean = true):Number 4071 { 4072 return transformWidthForLayout(preferredWidthPreTransform(), 4073 preferredHeightPreTransform(), 4074 postLayoutTransform); 4075 } 4076 4077 /** 4078 * @inheritDoc 4079 * 4080 * @langversion 3.0 4081 * @playerversion Flash 10 4082 * @playerversion AIR 1.5 4083 * @productversion Flex 4 4084 */ 4085 public function getPreferredBoundsHeight(postLayoutTransform:Boolean = true):Number 4086 { 4087 return transformHeightForLayout(preferredWidthPreTransform(), 4088 preferredHeightPreTransform(), 4089 postLayoutTransform); 4090 } 4091 4092 /** 4093 * @inheritDoc 4094 * 4095 * @langversion 3.0 4096 * @playerversion Flash 10 4097 * @playerversion AIR 1.5 4098 * @productversion Flex 4 4099 */ 4100 public function getBoundsXAtSize(width:Number, height:Number, postLayoutTransform:Boolean = true):Number 4101 { 4102 var strokeExtents:Rectangle = getStrokeExtents(postLayoutTransform); 4103 var m:Matrix = getComplexMatrix(postLayoutTransform); 4104 if (!m) 4105 return strokeExtents.left + this.measuredX + this.x; 4106 4107 if (!isNaN(width)) 4108 width -= strokeExtents.width; 4109 4110 if (!isNaN(height)) 4111 height -= strokeExtents.height; 4112 4113 // Calculate the width and height pre-transform: 4114 var newSize:Point = MatrixUtil.fitBounds(width, height, m, 4115 explicitWidth, explicitHeight, 4116 preferredWidthPreTransform(), 4117 preferredHeightPreTransform(), 4118 minWidth, minHeight, 4119 maxWidth, maxHeight); 4120 if (!newSize) 4121 newSize = new Point(minWidth, minHeight); 4122 4123 var topLeft:Point = new Point(measuredX, measuredY); 4124 MatrixUtil.transformBounds(newSize.x, newSize.y, m, topLeft); 4125 return strokeExtents.left + topLeft.x; 4126 } 4127 4128 /** 4129 * @inheritDoc 4130 * 4131 * @langversion 3.0 4132 * @playerversion Flash 10 4133 * @playerversion AIR 1.5 4134 * @productversion Flex 4 4135 */ 4136 public function getBoundsYAtSize(width:Number, height:Number, postLayoutTransform:Boolean = true):Number 4137 { 4138 var strokeExtents:Rectangle = getStrokeExtents(postLayoutTransform); 4139 var m:Matrix = getComplexMatrix(postLayoutTransform); 4140 if (!m) 4141 return strokeExtents.top + this.measuredY + this.y; 4142 4143 if (!isNaN(width)) 4144 width -= strokeExtents.width; 4145 4146 if (!isNaN(height)) 4147 height -= strokeExtents.height; 4148 4149 // Calculate the width and height pre-transform: 4150 var newSize:Point = MatrixUtil.fitBounds(width, height, m, 4151 explicitWidth, explicitHeight, 4152 preferredWidthPreTransform(), 4153 preferredHeightPreTransform(), 4154 minWidth, minHeight, 4155 maxWidth, maxHeight); 4156 if (!newSize) 4157 newSize = new Point(minWidth, minHeight); 4158 4159 var topLeft:Point = new Point(measuredX, measuredY); 4160 MatrixUtil.transformBounds(newSize.x, newSize.y, m, topLeft); 4161 return strokeExtents.top + topLeft.y; 4162 } 4163 4164 /** 4165 * @inheritDoc 4166 * 4167 * @langversion 3.0 4168 * @playerversion Flash 10 4169 * @playerversion AIR 1.5 4170 * @productversion Flex 4 4171 */ 4172 public function getLayoutBoundsX(postLayoutTransform:Boolean = true):Number 4173 { 4174 // Take stroke into account: 4175 var stroke:Number = getStrokeExtents(postLayoutTransform).left; 4176 4177 var m:Matrix = getComplexMatrix(postLayoutTransform); 4178 if (!m) 4179 return stroke + this.measuredX + this.x; 4180 4181 var topLeft:Point = new Point(measuredX, measuredY); 4182 MatrixUtil.transformBounds(_width, _height, m, topLeft); 4183 return stroke + topLeft.x; 4184 } 4185 4186 /** 4187 * @inheritDoc 4188 * 4189 * @langversion 3.0 4190 * @playerversion Flash 10 4191 * @playerversion AIR 1.5 4192 * @productversion Flex 4 4193 */ 4194 public function getLayoutBoundsY(postLayoutTransform:Boolean = true):Number 4195 { 4196 // Take stroke into account: 4197 var stroke:Number = getStrokeExtents(postLayoutTransform).top; 4198 4199 var m:Matrix = getComplexMatrix(postLayoutTransform); 4200 if (!m) 4201 return stroke + this.measuredY + this.y; 4202 4203 var topLeft:Point = new Point(measuredX, measuredY); 4204 MatrixUtil.transformBounds(_width, _height, m, topLeft); 4205 return stroke + topLeft.y; 4206 } 4207 4208 /** 4209 * @inheritDoc 4210 * 4211 * @langversion 3.0 4212 * @playerversion Flash 10 4213 * @playerversion AIR 1.5 4214 * @productversion Flex 4 4215 */ 4216 public function getLayoutBoundsWidth(postLayoutTransform:Boolean = true):Number 4217 { 4218 return transformWidthForLayout(_width, _height, postLayoutTransform); 4219 } 4220 4221 /** 4222 * @inheritDoc 4223 * 4224 * @langversion 3.0 4225 * @playerversion Flash 10 4226 * @playerversion AIR 1.5 4227 * @productversion Flex 4 4228 */ 4229 public function getLayoutBoundsHeight(postLayoutTransform:Boolean = true):Number 4230 { 4231 return transformHeightForLayout(_width, _height, postLayoutTransform); 4232 } 4233 4234 /** 4235 * Transform the element's size. 4236 * 4237 * <p>This method calculates the bounding box of the graphic element as if the element’s width/height properties were set to the passed in values. 4238 * The method returns the width of the bounding box.</p> 4239 * 4240 * <p>In general, this method is not for use by developers. Instead, you should implement or override the methods defined by the ILayoutElement interface.</p> 4241 * 4242 * @param width The target pre-transform width. 4243 * 4244 * @param height The target pre-transform height. 4245 * 4246 * @param postLayoutTransform When <code>true</code>, the returned bounding box is around the transformed element in its parent space (the element's transform is applied first). 4247 * 4248 * @return Returns the transformed width. Transformation is this element's 4249 * layout transformation matrix. 4250 * 4251 * @langversion 3.0 4252 * @playerversion Flash 10 4253 * @playerversion AIR 1.5 4254 * @productversion Flex 4 4255 */ 4256 protected function transformWidthForLayout(width:Number, 4257 height:Number, 4258 postLayoutTransform:Boolean = true):Number 4259 { 4260 if (postLayoutTransform && hasComplexLayoutMatrix) 4261 width = MatrixUtil.transformSize(width, height, 4262 layoutFeatures.layoutMatrix).x; 4263 4264 // Take stroke into account 4265 width += getStrokeExtents(postLayoutTransform).width; 4266 return width; 4267 } 4268 4269 /** 4270 * Transform the element's size. 4271 * 4272 * <p>This method calculates the bounding box of the graphic element as if the element’s width/height properties were set to the passed in values. 4273 * The method returns the height of the bounding box.</p> 4274 * 4275 * <p>In general, this method is not for use by developers. Instead, you should implement or override the methods defined by the ILayoutElement interface.</p> 4276 * 4277 * @param width The target pre-transform width. 4278 * 4279 * @param height The target pre-transform height. 4280 * 4281 * @param postLayoutTransform When <code>true</code>, the returned bounding box is around the transformed element in its parent space (the element's transform is applied first). 4282 * 4283 * @return Returns the transformed height. Transformation is this element's 4284 * layout transformation matrix. 4285 * 4286 * @langversion 3.0 4287 * @playerversion Flash 10 4288 * @playerversion AIR 1.5 4289 * @productversion Flex 4 4290 */ 4291 protected function transformHeightForLayout(width:Number, 4292 height:Number, 4293 postLayoutTransform:Boolean = true):Number 4294 { 4295 if (postLayoutTransform && hasComplexLayoutMatrix) 4296 height = MatrixUtil.transformSize(width, height, 4297 layoutFeatures.layoutMatrix).y; 4298 4299 // Take stroke into account 4300 height += getStrokeExtents(postLayoutTransform).height; 4301 return height; 4302 } 4303 4304 /** 4305 * Used for the implementation of the ILayoutElement interface, 4306 * returns the explicit of measured width pre-transform. 4307 * 4308 * @return The explicit measured height, pre-transform. 4309 * 4310 * @langversion 3.0 4311 * @playerversion Flash 10 4312 * @playerversion AIR 1.5 4313 * @productversion Flex 4 4314 */ 4315 protected function preferredWidthPreTransform():Number 4316 { 4317 return isNaN(explicitWidth) ? measuredWidth : explicitWidth; 4318 } 4319 4320 /** 4321 * Used for the implementation of the ILayoutElement interface, 4322 * returns the explicit measured height pre-transform. 4323 * 4324 * @return The explicit measured height, pre-transform. 4325 * 4326 * @langversion 3.0 4327 * @playerversion Flash 10 4328 * @playerversion AIR 1.5 4329 * @productversion Flex 4 4330 */ 4331 protected function preferredHeightPreTransform():Number 4332 { 4333 return isNaN(explicitHeight) ? measuredHeight: explicitHeight; 4334 } 4335 4336 /** 4337 * @inheritDoc 4338 * 4339 * @langversion 3.0 4340 * @playerversion Flash 10 4341 * @playerversion AIR 1.5 4342 * @productversion Flex 4 4343 */ 4344 public function setLayoutBoundsPosition(newBoundsX:Number, newBoundsY:Number, postLayoutTransform:Boolean = true):void 4345 { 4346 var currentBoundsX:Number = getLayoutBoundsX(postLayoutTransform); 4347 var currentBoundsY:Number = getLayoutBoundsY(postLayoutTransform); 4348 4349 var currentX:Number = this.x; 4350 var currentY:Number = this.y; 4351 4352 var newX:Number = currentX + newBoundsX - currentBoundsX; 4353 var newY:Number = currentY + newBoundsY - currentBoundsY; 4354 4355 if (newX != currentX || newY != currentY) 4356 { 4357 if (layoutFeatures != null) 4358 { 4359 layoutFeatures.layoutX = newX; 4360 layoutFeatures.layoutY = newY; 4361 4362 // note that we don't want to call invalidateTransform, because 4363 // this is in the middle of an update pass. Instead, we just note that the 4364 // transform has an update pending, so we can apply it later. 4365 layoutFeatures.updatePending = true; 4366 } 4367 else 4368 { 4369 _x = newX; 4370 _y = newY; 4371 } 4372 if (newX != currentX) 4373 dispatchPropertyChangeEvent("x", currentX, newX); 4374 if (newY != currentY) 4375 dispatchPropertyChangeEvent("y", currentY, newY); 4376 4377 invalidateDisplayList(); 4378 } 4379 } 4380 4381 /** 4382 * @inheritDoc 4383 * 4384 * @langversion 3.0 4385 * @playerversion Flash 10 4386 * @playerversion AIR 1.5 4387 * @productversion Flex 4 4388 */ 4389 public function setLayoutBoundsSize(width:Number, 4390 height:Number, 4391 postLayoutTransform:Boolean = true):void 4392 { 4393 if (!isNaN(width) || !isNaN(height)) 4394 { 4395 var strokeExtents:Rectangle = getStrokeExtents(postLayoutTransform); 4396 4397 if (!isNaN(width)) 4398 width -= strokeExtents.width; 4399 if (!isNaN(height)) 4400 height -= strokeExtents.height; 4401 } 4402 4403 // Calculate the width and height pre-transform: 4404 var m:Matrix; 4405 if (postLayoutTransform && hasComplexLayoutMatrix) 4406 m = layoutFeatures.layoutMatrix; 4407 if (!m) 4408 { 4409 if (isNaN(width)) 4410 width = preferredWidthPreTransform(); 4411 if (isNaN(height)) 4412 height = preferredHeightPreTransform(); 4413 } 4414 else 4415 { 4416 var newSize:Point = MatrixUtil.fitBounds(width, height, m, 4417 explicitWidth, explicitHeight, 4418 preferredWidthPreTransform(), 4419 preferredHeightPreTransform(), 4420 minWidth, minHeight, 4421 maxWidth, maxHeight); 4422 4423 if (newSize) 4424 { 4425 width = newSize.x; 4426 height = newSize.y; 4427 } 4428 else 4429 { 4430 width = minWidth; 4431 height = minHeight; 4432 } 4433 } 4434 4435 setActualSize(width, height); 4436 } 4437 4438 /** 4439 * @private 4440 */ 4441 mx_internal function setActualSize(width:Number, height:Number):void 4442 { 4443 if (_width != width || _height != height) 4444 { 4445 var oldWidth:Number = _width; 4446 var oldHeight:Number = _height; 4447 4448 _width = width; 4449 _height = height; 4450 4451 if (layoutFeatures) // mirroring transform depends on width 4452 { 4453 layoutFeatures.layoutWidth = width; 4454 invalidateTransform(false /*changeInvalidatesLayering*/, false /*invalidateLayout*/); 4455 } 4456 4457 if (width != oldWidth) 4458 dispatchPropertyChangeEvent("width", oldWidth, width); 4459 if (height != oldHeight) 4460 dispatchPropertyChangeEvent("height", oldHeight, height); 4461 4462 invalidateDisplayList(); 4463 } 4464 } 4465 4466 /** 4467 * @inheritDoc 4468 * 4469 * @langversion 3.0 4470 * @playerversion Flash 10 4471 * @playerversion AIR 1.5 4472 * @productversion Flex 4 4473 */ 4474 public function getLayoutMatrix():Matrix 4475 { 4476 // esg: _layoutFeatures keeps a single internal copy of the layoutMatrix. 4477 // since this is an internal class, we don't need to worry about developers 4478 // accidentally messing with this matrix, _unless_ we hand it out. Instead, 4479 // we hand out a clone. 4480 if (layoutFeatures != null) 4481 return layoutFeatures.layoutMatrix.clone(); 4482 var m:Matrix = new Matrix(); 4483 m.translate(_x,_y); 4484 return m; 4485 } 4486 4487 /** 4488 * @inheritDoc 4489 * 4490 * @langversion 3.0 4491 * @playerversion Flash 10 4492 * @playerversion AIR 1.5 4493 * @productversion Flex 4 4494 */ 4495 public function setLayoutMatrix(value:Matrix, invalidateLayout:Boolean):void 4496 { 4497 allocateLayoutFeatures(); 4498 var previous:Boolean = needsDisplayObject; 4499 4500 // Early exit if possible. We don't want to invalidate unnecessarily. 4501 if (MatrixUtil.isEqual(layoutFeatures.layoutMatrix, value)) 4502 return; 4503 4504 layoutFeatures.layoutMatrix = value; 4505 invalidateTransform(previous != needsDisplayObject, invalidateLayout); 4506 } 4507 4508 /** 4509 * @inheritDoc 4510 * 4511 * @langversion 3.0 4512 * @playerversion Flash 10 4513 * @playerversion AIR 1.5 4514 * @productversion Flex 4 4515 */ 4516 public function get hasLayoutMatrix3D():Boolean 4517 { 4518 return layoutFeatures ? layoutFeatures.layoutIs3D : false; 4519 } 4520 4521 /** 4522 * @inheritDoc 4523 * 4524 * @langversion 3.0 4525 * @playerversion Flash 10 4526 * @playerversion AIR 1.5 4527 * @productversion Flex 4 4528 */ 4529 public function get is3D():Boolean 4530 { 4531 return layoutFeatures ? layoutFeatures.is3D: false; 4532 } 4533 4534 /** 4535 * @inheritDoc 4536 * 4537 * @langversion 3.0 4538 * @playerversion Flash 10 4539 * @playerversion AIR 1.5 4540 * @productversion Flex 4 4541 */ 4542 public function getLayoutMatrix3D():Matrix3D 4543 { 4544 // esg: _layoutFeatures keeps a single internal copy of the layoutMatrix. 4545 // since this is an internal class, we don't need to worry about developers 4546 // accidentally messing with this matrix, _unless_ we hand it out. Instead, 4547 // we hand out a clone. 4548 if (layoutFeatures != null) 4549 return layoutFeatures.layoutMatrix3D.clone(); 4550 var m:Matrix3D = new Matrix3D(); 4551 m.appendTranslation(_x,_y,0); 4552 return m; 4553 } 4554 4555 /** 4556 * @inheritDoc 4557 * 4558 * @langversion 3.0 4559 * @playerversion Flash 10 4560 * @playerversion AIR 1.5 4561 * @productversion Flex 4 4562 */ 4563 public function setLayoutMatrix3D(value:Matrix3D, invalidateLayout:Boolean):void 4564 { 4565 allocateLayoutFeatures(); 4566 var previous:Boolean = needsDisplayObject; 4567 4568 // Early exit if possible. We don't want to invalidate unnecessarily. 4569 if (MatrixUtil.isEqual3D(layoutFeatures.layoutMatrix3D, value)) 4570 return; 4571 4572 layoutFeatures.layoutMatrix3D = value; 4573 invalidateTransform(previous != needsDisplayObject, invalidateLayout); 4574 } 4575 4576 /** 4577 * @private 4578 * Applies the transform to the DisplayObject. 4579 */ 4580 mx_internal function applyComputedTransform():void 4581 { 4582 if (layoutFeatures != null) 4583 layoutFeatures.updatePending = false; 4584 4585 // Only the first elment in the sequence updates the transform 4586 if (displayObjectSharingMode == DisplayObjectSharingMode.USES_SHARED_OBJECT || !displayObject) 4587 return; 4588 4589 if (layoutFeatures != null) 4590 { 4591 if (layoutFeatures.is3D) 4592 { 4593 displayObject.transform.matrix3D = layoutFeatures.computedMatrix3D; 4594 } 4595 else 4596 { 4597 var m:Matrix = layoutFeatures.computedMatrix.clone(); 4598 // If the displayObject is shared, then put it at 0,0 4599 if (displayObjectSharingMode == DisplayObjectSharingMode.OWNS_SHARED_OBJECT) 4600 { 4601 m.tx = 0; 4602 m.ty = 0; 4603 } 4604 displayObject.transform.matrix = m; 4605 } 4606 } 4607 else 4608 { 4609 // If the displayObject is shared, then put it at 0,0 4610 if (displayObjectSharingMode == DisplayObjectSharingMode.OWNS_SHARED_OBJECT) 4611 { 4612 displayObject.x = 0; 4613 displayObject.y = 0; 4614 } 4615 else 4616 { 4617 displayObject.x = _x; 4618 displayObject.y = _y; 4619 } 4620 } 4621 } 4622 4623 mx_internal function getComplexMatrix(performCheck:Boolean):Matrix 4624 { 4625 return performCheck && hasComplexLayoutMatrix ? layoutFeatures.layoutMatrix : null; 4626 } 4627 4628 static mx_internal var _strokeExtents:Rectangle = new Rectangle(); 4629 4630 /** 4631 * Returns the amount of pixels occupied by the stroke on each side 4632 * of the element's bounds. 4633 * 4634 * @param postLayoutTransform If <code>true</code>, the stroke extents are calculated 4635 * in parent coordinate space (after applying the element's transformations). 4636 * 4637 * @return Rectangle of the stroke extents. The rectangle's <code>left</code>, 4638 * <code>right</code>, <code>top</code> and <code>bottom</code> properties 4639 * represent the stroke extent for the respective side of the element's 4640 * bounding box. 4641 * 4642 * @langversion 3.0 4643 * @playerversion Flash 10 4644 * @playerversion AIR 1.5 4645 * @productversion Flex 4 4646 */ 4647 protected function getStrokeExtents(postLayoutTransform:Boolean = true):Rectangle 4648 { 4649 _strokeExtents.x = 0; 4650 _strokeExtents.y = 0; 4651 _strokeExtents.width = 0; 4652 _strokeExtents.height = 0; 4653 return _strokeExtents; 4654 } 4655 4656 //-------------------------------------------------------------------------- 4657 // 4658 // Event handlers 4659 // 4660 //-------------------------------------------------------------------------- 4661 4662 /** 4663 * @private 4664 * Called when a bitmap filter associated with the element is modified. 4665 */ 4666 private function filterChangedHandler(event:Event):void 4667 { 4668 filters = _filters; 4669 } 4670 4671} 4672 4673} 4674