You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by gr...@apache.org on 2021/12/17 19:08:12 UTC

[royale-asjs] branch develop updated (75511af -> dc935db)

This is an automated email from the ASF dual-hosted git repository.

gregdove pushed a change to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git.


    from 75511af  Added comment
     new 99d6bb9  Prep for emulation creationPolicy: foundation for deferred layouts and
     new 6d2a2dd  The dispatchEvent override needs the SWFOverride for swf
     new 7524dad  Support for now for creationPolicy='none', supporting the deferred layout functionality.
     new dc935db  updating example to show launch of LinkBar/Viewstack combo with children with creationPolicy=none.

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../src/main/royale/ControlsExample.mxml           |  28 ++-
 .../src/main/royale/components/StackItem.mxml      |  28 +++
 .../TitleWindowPopupWindowWithViewStack.mxml       |  49 +++++
 .../src/main/config/compile-swf-config.xml         |   1 +
 .../MXRoyale/src/main/resources/defaults.css       |   4 +-
 .../MXRoyale/src/main/royale/MXRoyaleClasses.as    |   1 +
 .../src/main/royale/mx/containers/ViewStack.as     |  11 +-
 .../beads}/supportClasses/ContainerContentArea.as  |   6 +-
 .../AdvancedDataGridHeaderRenderer.as              |   4 +-
 .../dataGridClasses/DataGridHeaderRenderer.as      |   4 +-
 .../mx/controls/listClasses/ListItemRenderer.as    |   4 +-
 .../MXRoyale/src/main/royale/mx/core/Container.as  | 240 +++++++++++++++++++--
 .../main/royale/mx/core/IDeferredContentOwner.as   | 103 +++++++++
 .../src/main/royale/mx/core/INavigatorContent.as   |   2 +-
 .../src/main/royale/mx/core/UIComponent.as         | 182 ++++++++++++++--
 .../src/main/royale/mx/events/FlexEvent.as         |   2 +-
 .../src/main/royale/spark/components/Grid.as       |   4 +-
 .../royale/spark/components/SkinnableContainer.as  |  20 +-
 .../supportClasses/SparkTextButtonItemRenderer.as  |   4 +-
 19 files changed, 629 insertions(+), 68 deletions(-)
 create mode 100644 examples/mxroyale/ControlsExample/src/main/royale/components/StackItem.mxml
 create mode 100644 examples/mxroyale/ControlsExample/src/main/royale/components/TitleWindowPopupWindowWithViewStack.mxml
 copy frameworks/projects/{Basic/src/main/royale/org/apache/royale/html => MXRoyale/src/main/royale/mx/containers/beads}/supportClasses/ContainerContentArea.as (94%)
 create mode 100644 frameworks/projects/MXRoyale/src/main/royale/mx/core/IDeferredContentOwner.as

[royale-asjs] 03/04: Support for now for creationPolicy='none', supporting the deferred layout functionality.

Posted by gr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gregdove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit 7524dadd4d745e2e0128ce229a4206e8f189b6a0
Author: greg-dove <gr...@gmail.com>
AuthorDate: Fri Dec 17 21:30:05 2021 +1300

    Support for now for creationPolicy='none', supporting the deferred layout functionality.
---
 .../MXRoyale/src/main/resources/defaults.css       |   4 +-
 .../MXRoyale/src/main/royale/MXRoyaleClasses.as    |   1 +
 .../src/main/royale/mx/containers/ViewStack.as     |  11 +-
 .../beads/supportClasses/ContainerContentArea.as   |  78 +++++++
 .../MXRoyale/src/main/royale/mx/core/Container.as  | 240 +++++++++++++++++++--
 .../main/royale/mx/core/IDeferredContentOwner.as   | 103 +++++++++
 .../src/main/royale/mx/core/INavigatorContent.as   |   2 +-
 .../src/main/royale/mx/events/FlexEvent.as         |   2 +-
 .../royale/spark/components/SkinnableContainer.as  |  20 +-
 9 files changed, 422 insertions(+), 39 deletions(-)

diff --git a/frameworks/projects/MXRoyale/src/main/resources/defaults.css b/frameworks/projects/MXRoyale/src/main/resources/defaults.css
index 2f40eb6..24d52a5 100644
--- a/frameworks/projects/MXRoyale/src/main/resources/defaults.css
+++ b/frameworks/projects/MXRoyale/src/main/resources/defaults.css
@@ -990,7 +990,7 @@ charts|DataTip
 	{
 		IBackgroundBead: ClassReference("org.apache.royale.html.beads.SolidBackgroundBead");
 		IBorderBead: ClassReference("org.apache.royale.html.beads.SingleLineBorderBead");
-		IContentView: ClassReference("org.apache.royale.html.supportClasses.ContainerContentArea");
+		IContentView: ClassReference("mx.containers.beads.supportClasses.ContainerContentArea");
 	}
 	
 	DataGrid {
@@ -1034,7 +1034,7 @@ charts|DataTip
 	
 	Panel
 	{
-		IContentView: ClassReference("org.apache.royale.html.supportClasses.ContainerContentArea");
+		IContentView: ClassReference("mx.containers.beads.supportClasses.ContainerContentArea");
 		IBorderBead: ClassReference("org.apache.royale.html.beads.SingleLineBorderBead");
 		IBackgroundBead: ClassReference("org.apache.royale.html.beads.SolidBackgroundBead");    
 	}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as b/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
index 4be7101..36daf24 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/MXRoyaleClasses.as
@@ -72,6 +72,7 @@ internal class MXRoyaleClasses
     import mx.containers.beads.layouts.BasicLayout; BasicLayout;
 	import mx.containers.beads.PanelInternalContainer; PanelInternalContainer;
 	import mx.containers.beads.PanelInternalContainerView; PanelInternalContainerView;
+	import mx.containers.beads.supportClasses.ContainerContentArea;ContainerContentArea;
 	import mx.controls.beads.AlertView; AlertView;
     import mx.controls.beads.controllers.AlertMouseController; AlertMouseController;
     import mx.containers.errors.ConstraintError; ConstraintError;
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/containers/ViewStack.as b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/ViewStack.as
index 1a3ba4e..ca9a9c8 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/containers/ViewStack.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/ViewStack.as
@@ -54,6 +54,10 @@ import mx.utils.RoyaleUtil;
 
 import org.apache.royale.core.IChild;
 
+import mx.events.ChildExistenceChangedEvent;
+import org.apache.royale.core.IUIBase;
+import mx.utils.RoyaleUtil;
+
 use namespace mx_internal;
 
 //--------------------------------------
@@ -965,13 +969,14 @@ public class ViewStack extends Container implements /*IHistoryManagerClient,*/ I
         super.updateDisplayList(unscaledWidth, unscaledHeight);
 
         var nChildren:int = numChildren;
+        if (!nChildren) return;
         var w:Number = contentWidth;
         var h:Number = contentHeight;
         var left:Number = contentX;
         var top:Number = contentY;
 
         // Stretch the selectedIndex to fill our size
-        if (nChildren && selectedIndex != -1)
+        if (selectedIndex != -1)
         {
             var child:UIComponent =
                 UIComponent(getChildAt(selectedIndex));
@@ -1274,16 +1279,14 @@ public class ViewStack extends Container implements /*IHistoryManagerClient,*/ I
         if (!selectedChild)
             return;
 
-        /*
         // Performance optimization: don't call createComponents if we know
         // that createComponents has already been called.
-        if (selectedChild && selectedChild.deferredContentCreated == false)
+        if (selectedChild && !selectedChild.deferredContentCreated)
         {
             if (initialized)  // Only listen if the ViewStack has already been initialized.
                 selectedChild.addEventListener(FlexEvent.CREATION_COMPLETE,childCreationCompleteHandler);
             selectedChild.createDeferredContent();
         }
-        */
 
         // Do the initial measurement/layout pass for the
         // newly-instantiated descendants.
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/containers/beads/supportClasses/ContainerContentArea.as b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/beads/supportClasses/ContainerContentArea.as
new file mode 100644
index 0000000..4768d25
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/containers/beads/supportClasses/ContainerContentArea.as
@@ -0,0 +1,78 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package mx.containers.beads.supportClasses
+{
+	import mx.core.UIComponent;
+
+	import org.apache.royale.core.IBead;
+	import org.apache.royale.core.IStrand;
+	import org.apache.royale.core.IUIBase;
+    import org.apache.royale.core.UIBase;
+    import org.apache.royale.events.Event;
+	import org.apache.royale.events.IEventDispatcher;
+	import org.apache.royale.core.IChild;
+	import org.apache.royale.core.ILayoutView;
+
+    /**
+     *  The ContainerContentArea class implements the contentView for
+     *  a Container on the SWF platform.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion Royale 0.0
+     */
+	public class ContainerContentArea extends UIComponent implements IBead, ILayoutView
+	{
+        /**
+         *  Constructor.
+         *
+         *  @langversion 3.0
+         *  @playerversion Flash 10.2
+         *  @playerversion AIR 2.6
+         *  @productversion Royale 0.0
+         */
+		public function ContainerContentArea()
+		{
+			super();
+            addEventListener("layoutNeeded", forwardEventHandler);
+		}
+		
+        private var _host:IUIBase;
+		public function get host():IUIBase
+        {
+            return _host;
+        }
+		/**
+		 *  @royaleignorecoercion org.apache.royale.core.IUIBase
+         */
+		public function set strand(value:IStrand):void
+		{
+			_host = value as IUIBase;
+		}
+        /**
+		 *  @royaleignorecoercion org.apache.royale.events.IEventDispatcher
+         */
+        private function forwardEventHandler(event:Event):void
+        {
+            if (parent is IEventDispatcher)
+                (parent as IEventDispatcher).dispatchEvent(event);
+        }
+	}
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/Container.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/Container.as
index 9c64770..789e0fe 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/core/Container.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/Container.as
@@ -19,7 +19,9 @@
 
 package mx.core
 {
-    import org.apache.royale.binding.ContainerDataBinding;
+import mx.events.ChildExistenceChangedEvent;
+
+import org.apache.royale.binding.ContainerDataBinding;
     import org.apache.royale.binding.DataBindingBase;
     import org.apache.royale.core.ContainerBaseStrandChildren;
     import org.apache.royale.core.IBeadLayout;
@@ -81,6 +83,7 @@ import mx.controls.listClasses.IListItemRenderer;
 import mx.events.FlexEvent;
 import mx.events.IndexChangedEvent;
 import mx.managers.IFocusManagerContainer;
+import org.apache.royale.utils.MXMLDataInterpreter;
 
 COMPILE::SWF
 {
@@ -1086,25 +1089,110 @@ public class Container extends UIComponent
 			// each MXML file can also have styles in fx:Style block
 			ValuesManager.valuesImpl.init(this);
 		}
-		
-		super.addedToParent();		
-		
+		const noChildrenNow:Boolean = creationPolicy == 'none';
+
+        if (noChildrenNow) _deferSetInitialized = true;
+		super.addedToParent();
+
 		// Load the layout bead if it hasn't already been loaded.
 		loadBeadFromValuesManager(IBeadLayout, "iBeadLayout", this);
-        dispatchEvent(new Event("initComplete"));
-        if ((isHeightSizedToContent() || !isNaN(explicitHeight)) &&
-            (isWidthSizedToContent() || !isNaN(explicitWidth)))
-			dispatchEvent(new Event("layoutNeeded"));
+        if (!noChildrenNow) {
+            //we don't want to run the states etc, they will error at this point
+            dispatchEvent(new Event("initComplete"));
+            if ((isHeightSizedToContent() || !isNaN(explicitHeight)) &&
+                    (isWidthSizedToContent() || !isNaN(explicitWidth)))
+                dispatchEvent(new Event("layoutNeeded"));
+        }
+
 	}
+
+
+    override public function initialize():void
+    {
+        if (initialized)
+            return;
+
+        if (creationPolicy == 'none') {
+            _deferSetInitialized = true;
+            dispatchEvent(new FlexEvent(FlexEvent.PREINITIALIZE));
+
+            _measuredWidth = NaN;
+            _measuredHeight = NaN;
+
+            // This should always be the last thing that initialize() calls.
+            initializationComplete();
+            return;
+        }
+        super.initialize();
+    }
 	
     override protected function createChildren():void
     {
+        if (creationPolicy == 'none') return;
         super.createChildren();
-        
-        if (getBeadByType(DataBindingBase) == null && '_bindings' in this /*mxmlDocument == this*/)
-            addBead(new ContainerDataBinding());
+        if ('_bindings' in this) {
+            if (getBeadByType(DataBindingBase) == null) {
+                addBead(new ContainerDataBinding());
+            }
+            dispatchEvent(new Event("initBindings"));
+        }
+    }
+
+
+    private var _deferSetInitialized:Boolean;
+    /**
+     *  @private
+     */
+    override public function set initialized(value:Boolean):void
+    {
+        if (value && !_deferSetInitialized) {
+            dispatchEvent(new FlexEvent(FlexEvent.CONTENT_CREATION_COMPLETE));
+            super.initialized = value;
+        } else {
+            _deferSetInitialized = false;
+        }
+    }
+
 
-        dispatchEvent(new Event("initBindings"));
+    override protected function initializationComplete():void
+    {
+        // Don't call super.initializationComplete().
+        //variation to flex sdk
+        //did we already create content ?
+        if (creationPolicy != 'none') {
+            super.initializationComplete();
+        }
+    }
+
+    /**
+     *  Performs the equivalent action of calling
+     *  the <code>createComponentsFromDescriptors(true)</code> method for containers
+     *  that implement the IDeferredContentOwner interface to support deferred instantiation.
+     *
+     *  @see #createComponentsFromDescriptors()
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    public function createDeferredContent():void
+    {
+        if (creationPolicy == 'none') {
+            creationPolicyNone = false;
+            _deferSetInitialized = false
+            createChildren();
+            //run the original addedToParent stuff
+            dispatchEvent(new Event("initComplete"));
+            if ((isHeightSizedToContent() || !isNaN(explicitHeight)) &&
+                    (isWidthSizedToContent() || !isNaN(explicitWidth)))
+                dispatchEvent(new Event("layoutNeeded"));
+
+            processedDescriptors = true;
+            creationPolicyNone = true;
+            //dispatchEvent(new FlexEvent(FlexEvent.CONTENT_CREATION_COMPLETE));
+            initialized = true;
+        }
     }
     
     /**
@@ -1152,13 +1240,78 @@ public class Container extends UIComponent
 	{
 		dispatchEvent( new Event("layoutNeeded") );
 	}
+
+
+
+    override mx_internal function addingChild(child:IUIBase):void
+    {
+
+        COMPILE::SWF{
+            //was
+            // Throw an RTE if child is not an IUIComponent.
+            //var uiChild:IUIComponent = IUIComponent(child);
+            if (!(child is IUIComponent)) {
+                //commented out for now, to allow legacy mustella tests to pass in swf
+              //  trace('this is child is not an IUIComponent', child )
+               // throw new Error('child is not IUIComponent '+child)
+            }
+
+        }
+
+
+        // Set the child's virtual parent, nestLevel, document, etc.
+        super.addingChild(child);
+
+        invalidateSize();
+        invalidateDisplayList();
+
+        /*if (!contentPane)
+        {
+            // If this is the first content child, then any chrome
+            // that already exists is positioned in front of it.
+            // If other content children already existed, then set the
+            // depth of this object to be just behind the existing
+            // content children.
+            if (_numChildren == 0)
+                _firstChildIndex = super.numChildren;
+
+            // Increment the number of content children.
+            _numChildren++;
+        }
+
+        if (contentPane && !autoLayout)
+        {
+            forceLayout = true;
+            // weak reference
+            UIComponentGlobals.layoutManager.addEventListener(
+                    FlexEvent.UPDATE_COMPLETE, layoutCompleteHandler, false, 0, true);
+        }*/
+    }
 	
     /**
      *  @private
      */
     override mx_internal function childAdded(child:IUIBase):void
     {
-		super.addingChild(child);
+        if (hasEventListener("childrenChanged"))
+            dispatchEvent(new Event("childrenChanged"));
+
+        if (hasEventListener(ChildExistenceChangedEvent.CHILD_ADD))
+        {
+            var event:ChildExistenceChangedEvent =
+                    new ChildExistenceChangedEvent(
+                            ChildExistenceChangedEvent.CHILD_ADD);
+            event.relatedObject = child as UIComponent;
+            dispatchEvent(event);
+        }
+
+       /* if (child.hasEventListener(FlexEvent.ADD))
+            child.dispatchEvent(new FlexEvent(FlexEvent.ADD));*/
+
+        //why is this calling addingChild in the super?
+	//	super.addingChild(child);
+        super.childAdded(child);
+
 		if (parent)
 		{
 			var oldMeasuredWidth:Number = measuredWidth;
@@ -1175,12 +1328,36 @@ public class Container extends UIComponent
 		}
 	}
 
+
+    /**
+     *  @private
+     */
+    override mx_internal function removingChild(child:IUIBase):void
+    {
+        super.removingChild(child);
+
+       /* if (child.hasEventListener(FlexEvent.REMOVE))
+            child.dispatchEvent(new FlexEvent(FlexEvent.REMOVE));*/
+
+        if (hasEventListener(ChildExistenceChangedEvent.CHILD_REMOVE))
+        {
+            var event:ChildExistenceChangedEvent =
+                    new ChildExistenceChangedEvent(
+                            ChildExistenceChangedEvent.CHILD_REMOVE);
+            event.relatedObject = child as UIComponent;
+            dispatchEvent(event);
+        }
+    }
+
     /**
      *  @private
      */
     override mx_internal function childRemoved(child:IUIBase):void
     {
-		super.removingChild(child);
+        //why is this calling removingChild in the super?
+		//super.removingChild(child);
+
+        super.childRemoved(child);
 		if (parent)
 		{
 			var oldMeasuredWidth:Number = measuredWidth;
@@ -1701,9 +1878,10 @@ public class Container extends UIComponent
         // don't have this property (ie Group).
         // This style is an implementation detail and should be considered
         // private. Do not set it from CSS.
-        /*if (creationPolicyNone)
-            return ContainerCreationPolicy.NONE;*/
-        return getStyle("_creationPolicy");
+        if (creationPolicyNone)
+            return ContainerCreationPolicy.NONE;
+        //return getStyle("_creationPolicy");
+        return  getStyle("_creationPolicy");
     }
 
     /**
@@ -1712,8 +1890,7 @@ public class Container extends UIComponent
     public function set creationPolicy(value:String):void
     {
         var styleValue:String = value;
-        
-        /*if (value == ContainerCreationPolicy.NONE)
+        if (value == ContainerCreationPolicy.NONE)
         {
             // creationPolicy of none is not inherited by descendants.
             // In this case, set the style to "auto" and set a local
@@ -1724,12 +1901,14 @@ public class Container extends UIComponent
         else
         {
             creationPolicyNone = false;
-        }*/
-        
+        }
         setStyle("_creationPolicy", styleValue);
 
         //setActualCreationPolicies(value);
     }
+
+
+    [Bindable("childrenChanged")]
     /**
      *  Returns an Array of DisplayObject objects consisting of the content children 
      *  of the container.
@@ -1799,6 +1978,25 @@ public class Container extends UIComponent
         */
         return super.contentMouseY; 
     }
+
+    //----------------------------------
+    //  deferredContentCreated
+    //----------------------------------
+
+    /**
+     *  IDeferredContentOwner equivalent of processedDescriptors
+     *
+     *  @see UIComponent#processedDescriptors
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function get deferredContentCreated():Boolean
+    {
+        return processedDescriptors;
+    }
 	
 	
 	    //----------------------------------
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/IDeferredContentOwner.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/IDeferredContentOwner.as
new file mode 100644
index 0000000..d9ca45f
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/IDeferredContentOwner.as
@@ -0,0 +1,103 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package mx.core
+{
+
+/**
+ *  Dispatched after the content for this component has been created. With deferred 
+ *  instantiation, the content for a component can be created long after the 
+ *  component is created.
+ *
+ *  @eventType mx.events.FlexEvent.CONTENT_CREATION_COMPLETE
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+[Event(name="contentCreationComplete", type="mx.events.FlexEvent")]
+
+/**
+ *  The IDeferredContentOwner interface defines the properties and methods
+ *  for deferred instantiation.
+ * 
+ *  @see spark.components.SkinnableContainer
+ *  @see mx.core.Container
+ *  @see mx.core.INavigatorContent
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 1.5
+ *  @productversion Flex 4
+ */
+public interface IDeferredContentOwner extends IUIComponent
+{
+    [Inspectable(enumeration="auto, all, none", defaultValue="auto")]
+
+    /**
+     *  Content creation policy for this component.
+     *
+     *  <p>Possible values are:
+     *    <ul>
+     *      <li><code>auto</code> - Automatically create the content immediately before it is needed.</li>
+     *      <li><code>all</code> - Create the content as soon as the parent component is created. This
+     *          option should only be used as a last resort because it increases startup time and memory usage.</li>
+     *      <li><code>none</code> - Content must be created manually by calling 
+     *          the <code>createDeferredContent()</code> method.</li>
+     *    </ul>
+     *  </p>
+     *  
+     *  <p>If no <code>creationPolicy</code> is specified for a container, that container inherits the value of 
+     *  its parent's <code>creationPolicy</code> property.</p>
+     *
+     *  @default "auto"
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    function get creationPolicy():String;
+    function set creationPolicy(value:String):void;
+
+    /**
+     *  Create the content for this component. If the value of the <code>creationPolicy</code> property
+     *  is <code>auto</code> or <code>all</code>, this the Flex framework calls this method. If the value of the 
+     *  <code>creationPolicy</code> property is <code>none</code>, you must explicitly call this method
+     *  to create the content for the component.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    function createDeferredContent():void;
+
+    /**
+     *  A flag that indicates whether the deferred content has been created.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    function get deferredContentCreated():Boolean;
+}
+
+}
\ No newline at end of file
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/INavigatorContent.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/INavigatorContent.as
index 0733639..f5f8c22 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/core/INavigatorContent.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/INavigatorContent.as
@@ -36,7 +36,7 @@ import mx.core.IUIComponent;
  *  @playerversion AIR 1.5
  *  @productversion Flex 4
  */
-public interface INavigatorContent extends IEventDispatcher,IUIComponent, IToolTipManagerClient // IDeferredContentOwner
+public interface INavigatorContent extends IEventDispatcher,IUIComponent,IDeferredContentOwner, IToolTipManagerClient
 {
     [Bindable("labelChanged")]
     /**
diff --git a/frameworks/projects/MXRoyaleBase/src/main/royale/mx/events/FlexEvent.as b/frameworks/projects/MXRoyaleBase/src/main/royale/mx/events/FlexEvent.as
index 2281d22..940e074 100644
--- a/frameworks/projects/MXRoyaleBase/src/main/royale/mx/events/FlexEvent.as
+++ b/frameworks/projects/MXRoyaleBase/src/main/royale/mx/events/FlexEvent.as
@@ -324,7 +324,7 @@ public class FlexEvent extends Event
      *  @playerversion AIR 1.1
      *  @productversion Flex 4
      */
-    //public static const CONTENT_CREATION_COMPLETE:String = "contentCreationComplete";
+    public static const CONTENT_CREATION_COMPLETE:String = "contentCreationComplete";
 
     
     /**
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/SkinnableContainer.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/SkinnableContainer.as
index e3a3725..8694745 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/SkinnableContainer.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/SkinnableContainer.as
@@ -1180,21 +1180,21 @@ public class SkinnableContainer extends SkinnableContainerBase implements IConta
      *  @playerversion AIR 1.5
      *  @productversion Royale 0.9.4
      */
-    /* public function createDeferredContent():void
-    {
+     public function createDeferredContent():void
+    {   //@todo similar fix as mx Container for creationPolicy NONE (at least)
         var children:Array =  this.MXMLDescriptor;
         if (children)
         {
-			creatingDeferredContent = true;
+			/*creatingDeferredContent = true;
             generateMXMLInstances(document, children);
 			creatingDeferredContent = false;
             mxmlContentCreated = true; // keep the code from recursing back into here.
             _deferredContentCreated = true; 
-            dispatchEvent(new FlexEvent(FlexEvent.CONTENT_CREATION_COMPLETE));
+            dispatchEvent(new FlexEvent(FlexEvent.CONTENT_CREATION_COMPLETE));*/
             return;
         }
         
-        if (!mxmlContentCreated)
+        /*if (!mxmlContentCreated)
         {
             mxmlContentCreated = true;
             
@@ -1205,11 +1205,11 @@ public class SkinnableContainer extends SkinnableContainerBase implements IConta
                 _deferredContentCreated = true;
                 dispatchEvent(new FlexEvent(FlexEvent.CONTENT_CREATION_COMPLETE));
             }
-        }
+        }*/
     }
-
+    //@todo similar fix as mx for creationPolicy NONE (at least)
     private var _deferredContentCreated:Boolean;
-    */
+
     /**
      *  Contains <code>true</code> if deferred content has been created.
      *  
@@ -1218,10 +1218,10 @@ public class SkinnableContainer extends SkinnableContainerBase implements IConta
      *  @playerversion AIR 1.5
      *  @productversion Royale 0.9.4
      */
-    /* public function get deferredContentCreated():Boolean
+     public function get deferredContentCreated():Boolean
     {
         return _deferredContentCreated;
-    } */
+    }
 
     /**
      *  @private

[royale-asjs] 02/04: The dispatchEvent override needs the SWFOverride for swf

Posted by gr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gregdove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit 6d2a2dd07a3e7dcdff69a645c6d4a6653fe55a76
Author: greg-dove <gr...@gmail.com>
AuthorDate: Fri Dec 17 23:39:04 2021 +1300

    The dispatchEvent override needs the SWFOverride for swf
---
 .../src/main/config/compile-swf-config.xml         |  1 +
 .../src/main/royale/mx/core/UIComponent.as         | 23 ++++++++++++----------
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/frameworks/projects/MXRoyale/src/main/config/compile-swf-config.xml b/frameworks/projects/MXRoyale/src/main/config/compile-swf-config.xml
index 19c8d72..96a1926 100644
--- a/frameworks/projects/MXRoyale/src/main/config/compile-swf-config.xml
+++ b/frameworks/projects/MXRoyale/src/main/config/compile-swf-config.xml
@@ -67,6 +67,7 @@
           <name>ChangeEvent</name>
           <name>NonCommittingChangeEvent</name>
           <name>Transient</name>
+          <name>SWFOverride</name>
         </keep-as3-metadata>
 	  
         <locale/>
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
index d0e56cf..fa954ef 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
@@ -4479,18 +4479,21 @@ COMPILE::JS
      * @productversion Royale 0.9.9
      */
     COMPILE::SWF
-    override public function dispatchEvent(event:Event):Boolean{
-        //trap the layout requests and ignore them if we have deferred layout
-        if (event.type == "layoutNeeded") {
-            if (_layoutDeferred) {
-                _needsLayout = true;
-                return false;
-            } else {
-                //layout will run, no 'need' to re-run later
-                _needsLayout = false;
+    {
+        [SWFOverride(params="flash.events.Event", altparams="org.apache.royale.events.Event:org.apache.royale.events.MouseEvent")]
+        override public function dispatchEvent(event:Event):Boolean {
+            //trap the layout requests and ignore them if we have deferred layout
+            if (event.type == "layoutNeeded") {
+                if (_layoutDeferred) {
+                    _needsLayout = true;
+                    return false;
+                } else {
+                    //layout will run, no 'need' to re-run later
+                    _needsLayout = false;
+                }
             }
+            return super.dispatchEvent(event);
         }
-        return super.dispatchEvent(event);
     }
 
     /**

[royale-asjs] 04/04: updating example to show launch of LinkBar/Viewstack combo with children with creationPolicy=none.

Posted by gr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gregdove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit dc935db7fbf8cf8d09be55efc8e1b2bf260a038c
Author: greg-dove <gr...@gmail.com>
AuthorDate: Fri Dec 17 21:45:42 2021 +1300

    updating example to show launch of LinkBar/Viewstack combo with children with creationPolicy=none.
---
 .../src/main/royale/ControlsExample.mxml           | 28 +++++++++++--
 .../src/main/royale/components/StackItem.mxml      | 28 +++++++++++++
 .../TitleWindowPopupWindowWithViewStack.mxml       | 49 ++++++++++++++++++++++
 3 files changed, 101 insertions(+), 4 deletions(-)

diff --git a/examples/mxroyale/ControlsExample/src/main/royale/ControlsExample.mxml b/examples/mxroyale/ControlsExample/src/main/royale/ControlsExample.mxml
index 890c442..3600e83 100644
--- a/examples/mxroyale/ControlsExample/src/main/royale/ControlsExample.mxml
+++ b/examples/mxroyale/ControlsExample/src/main/royale/ControlsExample.mxml
@@ -42,10 +42,11 @@ limitations under the License.
 	
 	<fx:Script>
 		<![CDATA[
+		import components.TitleWindowPopupWindowWithViewStack;
 		import mx.containers.TitleWindow;
-		import mx.events.CloseEvent;
 		import mx.managers.PopUpManager;
-
+		import mx.events.CloseEvent;
+		import mx.events.FlexEvent;
 		import org.apache.royale.events.Event;
 
 		private function pushMePushed(event:MouseEvent):void {
@@ -74,9 +75,26 @@ limitations under the License.
 			PopUpManager.addPopUp(titleWindow, this, true);
 			PopUpManager.centerPopUp(titleWindow);
 		}
+
+		private function testViewStack():void {
+			var test:TitleWindowPopupWindowWithViewStack = PopUpManager.createPopUp(this,TitleWindowPopupWindowWithViewStack) as TitleWindowPopupWindowWithViewStack;
+			test.addEventListener(mx.events.CloseEvent.CLOSE, close);
+			//@todo implement and test other child creationPolicies...
+			test.childCreationPolicyTest = 'none';
+			test.title = "ViewStack with creationPolicy test:"+test.childCreationPolicyTest;
+			PopUpManager.centerPopUp(test);
+
+			function close(event:mx.events.CloseEvent):void{
+				PopUpManager.removePopUp(test)
+			}
+		}
 		]]>
 	</fx:Script>
-	
+	<mx:Canvas width="300" height="100" backgroundColor="yellow">
+		<mx:Label text="left:2 right:2 top:2" left="2" right="2" top="2" backgroundColor="white"/>
+		<mx:Label text="left:10 right:40 top:40" left="10" right="40" top="40" backgroundColor="white"/>
+		<mx:Label text="left:40 right:40 top:80" left="40" right="40" top="80" backgroundColor="white" />
+	</mx:Canvas>
 	<mx:VBox id="vbox1">
 		<mx:Label text="Hello World"/>
 		<mx:Button label="Change Icon" click="changeIcon()"
@@ -109,5 +127,7 @@ limitations under the License.
 		maxChars="100"/>
 	<mx:Button label="Launch TitleWindow" click="testTitleWindow()"
 			   toolTip="launchs a test TitleWindow" />
-        
+	<mx:Button label="Launch ViewStack" click="testViewStack()"
+			   toolTip="launchs a test ViewStack with LinkBar" />
+
 </mx:Application>
\ No newline at end of file
diff --git a/examples/mxroyale/ControlsExample/src/main/royale/components/StackItem.mxml b/examples/mxroyale/ControlsExample/src/main/royale/components/StackItem.mxml
new file mode 100644
index 0000000..58e5170
--- /dev/null
+++ b/examples/mxroyale/ControlsExample/src/main/royale/components/StackItem.mxml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<mx:Canvas xmlns:fx="http://ns.adobe.com/mxml/2009"
+           xmlns:mx="library://ns.apache.org/royale/mx"
+
+           width="100%" height="100%">
+
+    <mx:Label preinitialize="preInitialize(event)" initialize="onInitialize(event)" id="testLabel" left="0" right="0" text="{label}" creationComplete="labelComplete(event)"/>
+
+    <mx:Label preinitialize="preInitialize(event)" initialize="onInitialize(event)" id="otherLabel" left="0" right="0" top="40" text="{label}" creationComplete="labelComplete(event)"/>
+
+    <fx:Script><![CDATA[
+        import mx.events.FlexEvent;
+
+
+        private function labelComplete(event:FlexEvent):void{
+            trace(event.target.id,' creationComplete Internal:'+this.label)
+        }
+
+
+        private function preInitialize(event:FlexEvent):void {
+            trace(event.target.id,' preInitialize Internal:'+this.label)
+        }
+
+        private function onInitialize(event:FlexEvent):void {
+            trace(event.target.id,' initialize Internal:'+this.label)
+        }
+        ]]></fx:Script>
+</mx:Canvas>
diff --git a/examples/mxroyale/ControlsExample/src/main/royale/components/TitleWindowPopupWindowWithViewStack.mxml b/examples/mxroyale/ControlsExample/src/main/royale/components/TitleWindowPopupWindowWithViewStack.mxml
new file mode 100644
index 0000000..f7169f7
--- /dev/null
+++ b/examples/mxroyale/ControlsExample/src/main/royale/components/TitleWindowPopupWindowWithViewStack.mxml
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<mx:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
+                xmlns:mx="library://ns.apache.org/royale/mx"
+                layout="absolute"
+                creationComplete="onCreationComplete(event)"
+                showCloseButton="true"
+                width="850"
+                height="680">
+
+    <fx:Script><![CDATA[
+        import mx.events.FlexEvent;
+
+        public var childCreationPolicyTest:String = 'none';
+
+        private function viewStackChange(event:IndexChangedEvent):void {
+
+        }
+        import mx.events.IndexChangedEvent;
+
+        private function onCreationComplete(event:FlexEvent):void {
+            for (var i:uint=0;i<10;i++) {
+                var inst:Canvas = new StackItem();
+                inst.creationPolicy = i >0 ? childCreationPolicyTest : 'all';
+                inst.label = "Inst:"+i;
+                inst.addEventListener(FlexEvent.PREINITIALIZE, childEvent);
+                inst.addEventListener(FlexEvent.INITIALIZE, childEvent)
+                inst.addEventListener(FlexEvent.CREATION_COMPLETE, childEvent)
+                inst.addEventListener(FlexEvent.CONTENT_CREATION_COMPLETE, childEvent)
+                Properties_vs.addChild(inst);
+            }
+
+        }
+
+
+        private function childEvent(event:Event):void{
+            var target:StackItem = event.target as StackItem;
+            trace(event.type, target.label);
+        }
+
+        ]]>
+    </fx:Script>
+    <mx:Canvas width="223" left="0" top="0" bottom="0" horizontalScrollPolicy="off" id="linkBarCanvas">
+        <mx:LinkBar id="Properties_lbar" width="215" direction="vertical" dataProvider="Properties_vs" left="0" top="0" bottom="0"/>
+    </mx:Canvas>
+    <mx:VRule x="223" top="0" bottom="0" id="propertiesVRule"/>
+    <mx:ViewStack id="Properties_vs" change="viewStackChange(event)" top="0" bottom="0" right="0" left="225"/>
+
+
+</mx:TitleWindow>

RE: [royale-asjs] 01/04: Prep for emulation creationPolicy: foundation for deferred layouts and

Posted by Yishay Weiss <yi...@hotmail.com>.
I hope I fixed this with 768cf0073a826e6cf058e56c673fdf7d92f64bcf

________________________________
From: Yishay Weiss <yi...@hotmail.com>
Sent: Thursday, December 23, 2021 6:32:39 PM
To: dev@royale.apache.org <de...@royale.apache.org>; commits@royale.apache.org <co...@royale.apache.org>; greg.dove@gmail.com <gr...@gmail.com>
Subject: RE: [royale-asjs] 01/04: Prep for emulation creationPolicy: foundation for deferred layouts and

     protected function createChildren():void
     {
-        MXMLDataInterpreter.generateMXMLInstances(mxmlDocument, this, MXMLDescriptor);
+        var children:Array =  this.MXMLDescriptor;
+        if (children && children.length && !processedMXMLDescriptors) {
+            layoutDeferred = true;
+            MXMLDataInterpreter.generateMXMLInstances(mxmlDocument, this, children);
+            layoutDeferred = false;
+            processedMXMLDescriptors = true;
+        }
     }

@greg.dove@gmail.com<ma...@gmail.com>, I think this is creating a problem in FormItem (after I avoid the measurement issue which may be separate).

+            processedMXMLDescriptors = false;

Triggers a layout which references the form item’s label object before it is created. The reason this happens is because FormItem.createChildren() calls super before creating the labelObject.

Maybe this flag should be set only after initialized is true?

From: gregdove@apache.org<ma...@apache.org>
Sent: Friday, December 17, 2021 9:08 PM
To: commits@royale.apache.org<ma...@royale.apache.org>
Subject: [royale-asjs] 01/04: Prep for emulation creationPolicy: foundation for deferred layouts and

This is an automated email from the ASF dual-hosted git repository.

gregdove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit 99d6bb9b556d98106bf69d8557078215914994ba
Author: greg-dove <gr...@gmail.com>
AuthorDate: Fri Dec 17 12:15:36 2021 +1300

    Prep for emulation creationPolicy: foundation for deferred layouts and
---
 .../AdvancedDataGridHeaderRenderer.as              |   4 +-
 .../dataGridClasses/DataGridHeaderRenderer.as      |   4 +-
 .../mx/controls/listClasses/ListItemRenderer.as    |   4 +-
 .../src/main/royale/mx/core/UIComponent.as         | 179 +++++++++++++++++++--
 .../src/main/royale/spark/components/Grid.as       |   4 +-
 .../supportClasses/SparkTextButtonItemRenderer.as  |   4 +-
 6 files changed, 176 insertions(+), 23 deletions(-)

diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/advancedDataGridClasses/AdvancedDataGridHeaderRenderer.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/advancedDataGridClasses/AdvancedDataGridHeaderRenderer.as
index 66c3989..074fa74 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/advancedDataGridClasses/AdvancedDataGridHeaderRenderer.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/advancedDataGridClasses/AdvancedDataGridHeaderRenderer.as
@@ -1012,7 +1012,7 @@ public class AdvancedDataGridHeaderRenderer extends UIComponent implements IData
         throw new Error("Method not implemented.");
     }

-    public function get processedDescriptors():Boolean
+    /*public function get processedDescriptors():Boolean
     {
         throw new Error("Method not implemented.");
     }
@@ -1020,7 +1020,7 @@ public class AdvancedDataGridHeaderRenderer extends UIComponent implements IData
     public function set processedDescriptors(value:Boolean):void
     {
         throw new Error("Method not implemented.");
-    }
+    }*/

     public function get updateCompletePendingFlag():Boolean
     {
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/dataGridClasses/DataGridHeaderRenderer.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/dataGridClasses/DataGridHeaderRenderer.as
index 628abeb..f3d21e9 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/dataGridClasses/DataGridHeaderRenderer.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/dataGridClasses/DataGridHeaderRenderer.as
@@ -1010,7 +1010,7 @@ public class DataGridHeaderRenderer extends UIComponent implements IDataRenderer
         throw new Error("Method not implemented.");
     }

-    public function get processedDescriptors():Boolean
+    /*public function get processedDescriptors():Boolean
     {
         throw new Error("Method not implemented.");
     }
@@ -1018,7 +1018,7 @@ public class DataGridHeaderRenderer extends UIComponent implements IDataRenderer
     public function set processedDescriptors(value:Boolean):void
     {
         throw new Error("Method not implemented.");
-    }
+    }*/

     public function get updateCompletePendingFlag():Boolean
     {
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListItemRenderer.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListItemRenderer.as
index 4412721..7116cc8 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListItemRenderer.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListItemRenderer.as
@@ -313,7 +313,7 @@ public class ListItemRenderer extends UIComponent implements IListItemRenderer,
         throw new Error("Method not implemented.");
     }

-    public function get processedDescriptors():Boolean
+    /*public function get processedDescriptors():Boolean
     {
         throw new Error("Method not implemented.");
     }
@@ -321,7 +321,7 @@ public class ListItemRenderer extends UIComponent implements IListItemRenderer,
     public function set processedDescriptors(value:Boolean):void
     {
         throw new Error("Method not implemented.");
-    }
+    }*/

     public function get updateCompletePendingFlag():Boolean
     {
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
index 857004e..d0e56cf 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
@@ -39,6 +39,8 @@ import flash.events.IEventDispatcher;

 import mx.controls.beads.ToolTipBead;
 import mx.core.mx_internal;
+import mx.managers.IToolTipManagerClient;
+
 COMPILE::SWF
 {
 import flash.display.DisplayObject;
@@ -761,7 +763,7 @@ public class UIComponent extends UIBase
     IMXMLDocument,
     IInvalidating,
     IStatesObject,
-    ISimpleStyleClient,
+    ISimpleStyleClient,IToolTipManagerClient,
     IUIComponent, IVisualElement, IFlexModule, IValidatorListener
 {
     //--------------------------------------------------------------------------
@@ -1123,6 +1125,10 @@ public class UIComponent extends UIBase

         if (value)
         {
+            if (_needsLayout) {
+                //invalidateSize();
+                dispatchEvent(new Event('layoutNeeded'));
+            }
             dispatchEvent(new FlexEvent(FlexEvent.CREATION_COMPLETE));
         }
     }
@@ -2692,10 +2698,15 @@ COMPILE::JS
                     for (var i:int = 0; i < numChildren; i++)
                     {
                         var child:IUIComponent = getChildAt(i);
-                        if (child) // child is null for TextNodes
+                        //@todo investigate traces
+                        if (child is IUIComponent) // child is null for TextNodes
                             mw = Math.max(mw, child.getExplicitOrMeasuredWidth());
-                        else
-                            trace("Child class not IUIComponent: " + getQualifiedClassName(getElementAt(i)));
+                        else {
+                            if (child is IUIBase) {
+                                mw = Math.max(mw, child.width);
+                            }
+                            trace(getQualifiedClassName(this) + " Child class not IUIComponent: " + getQualifiedClassName(getElementAt(i)));
+                        }
                     }
                 }
                 if (oldWidth.length)
@@ -2768,10 +2779,15 @@ COMPILE::JS
                     for (var i:int = 0; i < numChildren; i++)
                     {
                         var child:IUIComponent = getChildAt(i);
-                        if (child)
+                        //@todo investigate traces
+                        if (child is IUIComponent) // child is null for TextNodes
                             mh = Math.max(mh, child.getExplicitOrMeasuredHeight());
-                        else
-                            trace("Child class not IUIComponent: " + getQualifiedClassName(getElementAt(i)));
+                        else {
+                            if (child is IUIBase) {
+                                mh = Math.max(mh, child.height);
+                            }
+                            trace(getQualifiedClassName(this) + " Child class not IUIComponent: " + getQualifiedClassName(getElementAt(i)));
+                        }
                     }
                 }
                 if (oldHeight.length)
@@ -4006,8 +4022,8 @@ COMPILE::JS
                         var n:int = arr.length;
                         var num:int = 0;
                         for (var i:int = 0; i < n; i++)
-                       {
-                               if ((arr[i] as WrappedHTMLElement).royale_wrapper)
+                       {   //@todo review issuses with internal native support that points to 'this' (2nd check below), can cause infinite recursion in measurement if avoided:
+                               if ((arr[i] as WrappedHTMLElement).royale_wrapper && (arr[i] as WrappedHTMLElement).royale_wrapper != this)
                                         num++;
                         }
                         return num;
@@ -4193,8 +4209,61 @@ COMPILE::JS
      */
     protected function initializationComplete():void
     {
-        dispatchEvent(new FlexEvent(FlexEvent.INITIALIZE));
-    }
+        processedDescriptors = true;
+    }
+
+        //----------------------------------
+        //  processedDescriptors
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the processedDescriptors property.
+         */
+        private var _processedDescriptors:Boolean = false;
+
+        [Inspectable(environment="none")]
+
+        /**
+         *  Set to <code>true</code> after immediate or deferred child creation,
+         *  depending on which one happens. For a Container object, it is set
+         *  to <code>true</code> at the end of
+         *  the <code>createComponentsFromDescriptors()</code> method,
+         *  meaning after the Container object creates its children from its child descriptors.
+         *
+         *  <p>For example, if an Accordion container uses deferred instantiation,
+         *  the <code>processedDescriptors</code> property for the second pane of
+         *  the Accordion container does not become <code>true</code> until after
+         *  the user navigates to that pane and the pane creates its children.
+         *  But, if the Accordion had set the <code>creationPolicy</code> property
+         *  to <code>"all"</code>, the <code>processedDescriptors</code> property
+         *  for its second pane is set to <code>true</code> during application startup.</p>
+         *
+         *  <p>For classes that are not containers, which do not have descriptors,
+         *  it is set to <code>true</code> after the <code>createChildren()</code>
+         *  method creates any internal component children.</p>
+         *
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get processedDescriptors():Boolean
+        {
+            return _processedDescriptors;
+        }
+
+        /**
+         *  @private
+         */
+        public function set processedDescriptors(value:Boolean):void
+        {
+            _processedDescriptors = value;
+
+            if (value)
+                dispatchEvent(new FlexEvent(FlexEvent.INITIALIZE));
+        }
+

     /**
      *  Create child objects of the component.
@@ -4221,9 +4290,17 @@ COMPILE::JS
      */
     protected function createChildren():void
     {
-        MXMLDataInterpreter.generateMXMLInstances(mxmlDocument, this, MXMLDescriptor);
+        var children:Array =  this.MXMLDescriptor;
+        if (children && children.length && !processedMXMLDescriptors) {
+            layoutDeferred = true;
+            MXMLDataInterpreter.generateMXMLInstances(mxmlDocument, this, children);
+            layoutDeferred = false;
+            processedMXMLDescriptors = true;
+        }
     }
-
+
+    private var processedMXMLDescriptors : Boolean;
+
     private var _mxmlDescriptor:Array;

     /**
@@ -4340,6 +4417,82 @@ COMPILE::JS
             (parent as IEventDispatcher).dispatchEvent(new Event("layoutNeeded")); // might cause too many layouts
     }

+    private var _layoutDeferred:Boolean;
+    /**
+     *  Support for deferred layout requests
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     * @productversion Royale 0.9.9
+     */
+    protected function get layoutDeferred():Boolean{
+        return _layoutDeferred
+    }
+    protected function set layoutDeferred(value:Boolean):void{
+        _layoutDeferred = value;
+        if (!value && _needsLayout) {
+            dispatchEvent(new Event('layoutNeeded'));
+        }
+    }
+    private var _needsLayout:Boolean;
+    /**
+     *  Support for deferred layout requests
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     * @productversion Royale 0.9.9
+     */
+    protected function get needsLayout():Boolean{
+        return _needsLayout;
+    }
+
+    /**
+     *  Support for deferred layout requests
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     * @productversion Royale 0.9.9
+     */
+    COMPILE::JS
+    override public function dispatchEvent(event:Object):Boolean{
+        //trap the layout requests and ignore them if we have deferred layout
+        if (event.type == "layoutNeeded" || event == 'layoutNeeded') {
+            if (_layoutDeferred) {
+                _needsLayout = true;
+                return false;
+            } else {
+                //layout will run, no 'need' to re-run later
+                _needsLayout = false;
+            }
+        }
+        return super.dispatchEvent(event);
+    }
+    /**
+     *  Support for deferred layout requests
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     * @productversion Royale 0.9.9
+     */
+    COMPILE::SWF
+    override public function dispatchEvent(event:Event):Boolean{
+        //trap the layout requests and ignore them if we have deferred layout
+        if (event.type == "layoutNeeded") {
+            if (_layoutDeferred) {
+                _needsLayout = true;
+                return false;
+            } else {
+                //layout will run, no 'need' to re-run later
+                _needsLayout = false;
+            }
+        }
+        return super.dispatchEvent(event);
+    }
+
     /**
      *  Helper method to invalidate parent size and display list if
      *  this object affects its layout (includeInLayout is true).
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Grid.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Grid.as
index 276c35a..e5170265 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Grid.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Grid.as
@@ -6022,13 +6022,13 @@ package spark.components
                         return 0;
                 }

-               public function set processedDescriptors(value:Boolean):void {
+               /*public function set processedDescriptors(value:Boolean):void {

                 }

                 public function get processedDescriptors():Boolean {
                         return false;
-               }
+               }*/

                 public function set updateCompletePendingFlag(value:Boolean):void {

diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SparkTextButtonItemRenderer.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SparkTextButtonItemRenderer.as
index b288837..ac67469 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SparkTextButtonItemRenderer.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SparkTextButtonItemRenderer.as
@@ -273,7 +273,7 @@ package spark.components.supportClasses
             throw new Error("Method not implemented.");
         }

-        public function get processedDescriptors():Boolean
+       /* public function get processedDescriptors():Boolean
         {
             throw new Error("Method not implemented.");
         }
@@ -281,7 +281,7 @@ package spark.components.supportClasses
         public function set processedDescriptors(value:Boolean):void
         {
             throw new Error("Method not implemented.");
-        }
+        }*/

         public function get updateCompletePendingFlag():Boolean
         {


RE: [royale-asjs] 01/04: Prep for emulation creationPolicy: foundation for deferred layouts and

Posted by Yishay Weiss <yi...@hotmail.com>.
     protected function createChildren():void
     {
-        MXMLDataInterpreter.generateMXMLInstances(mxmlDocument, this, MXMLDescriptor);
+        var children:Array =  this.MXMLDescriptor;
+        if (children && children.length && !processedMXMLDescriptors) {
+            layoutDeferred = true;
+            MXMLDataInterpreter.generateMXMLInstances(mxmlDocument, this, children);
+            layoutDeferred = false;
+            processedMXMLDescriptors = true;
+        }
     }

@greg.dove@gmail.com<ma...@gmail.com>, I think this is creating a problem in FormItem (after I avoid the measurement issue which may be separate).

+            processedMXMLDescriptors = false;

Triggers a layout which references the form item’s label object before it is created. The reason this happens is because FormItem.createChildren() calls super before creating the labelObject.

Maybe this flag should be set only after initialized is true?

From: gregdove@apache.org<ma...@apache.org>
Sent: Friday, December 17, 2021 9:08 PM
To: commits@royale.apache.org<ma...@royale.apache.org>
Subject: [royale-asjs] 01/04: Prep for emulation creationPolicy: foundation for deferred layouts and

This is an automated email from the ASF dual-hosted git repository.

gregdove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit 99d6bb9b556d98106bf69d8557078215914994ba
Author: greg-dove <gr...@gmail.com>
AuthorDate: Fri Dec 17 12:15:36 2021 +1300

    Prep for emulation creationPolicy: foundation for deferred layouts and
---
 .../AdvancedDataGridHeaderRenderer.as              |   4 +-
 .../dataGridClasses/DataGridHeaderRenderer.as      |   4 +-
 .../mx/controls/listClasses/ListItemRenderer.as    |   4 +-
 .../src/main/royale/mx/core/UIComponent.as         | 179 +++++++++++++++++++--
 .../src/main/royale/spark/components/Grid.as       |   4 +-
 .../supportClasses/SparkTextButtonItemRenderer.as  |   4 +-
 6 files changed, 176 insertions(+), 23 deletions(-)

diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/advancedDataGridClasses/AdvancedDataGridHeaderRenderer.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/advancedDataGridClasses/AdvancedDataGridHeaderRenderer.as
index 66c3989..074fa74 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/advancedDataGridClasses/AdvancedDataGridHeaderRenderer.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/advancedDataGridClasses/AdvancedDataGridHeaderRenderer.as
@@ -1012,7 +1012,7 @@ public class AdvancedDataGridHeaderRenderer extends UIComponent implements IData
         throw new Error("Method not implemented.");
     }

-    public function get processedDescriptors():Boolean
+    /*public function get processedDescriptors():Boolean
     {
         throw new Error("Method not implemented.");
     }
@@ -1020,7 +1020,7 @@ public class AdvancedDataGridHeaderRenderer extends UIComponent implements IData
     public function set processedDescriptors(value:Boolean):void
     {
         throw new Error("Method not implemented.");
-    }
+    }*/

     public function get updateCompletePendingFlag():Boolean
     {
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/dataGridClasses/DataGridHeaderRenderer.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/dataGridClasses/DataGridHeaderRenderer.as
index 628abeb..f3d21e9 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/dataGridClasses/DataGridHeaderRenderer.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/dataGridClasses/DataGridHeaderRenderer.as
@@ -1010,7 +1010,7 @@ public class DataGridHeaderRenderer extends UIComponent implements IDataRenderer
         throw new Error("Method not implemented.");
     }

-    public function get processedDescriptors():Boolean
+    /*public function get processedDescriptors():Boolean
     {
         throw new Error("Method not implemented.");
     }
@@ -1018,7 +1018,7 @@ public class DataGridHeaderRenderer extends UIComponent implements IDataRenderer
     public function set processedDescriptors(value:Boolean):void
     {
         throw new Error("Method not implemented.");
-    }
+    }*/

     public function get updateCompletePendingFlag():Boolean
     {
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListItemRenderer.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListItemRenderer.as
index 4412721..7116cc8 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListItemRenderer.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListItemRenderer.as
@@ -313,7 +313,7 @@ public class ListItemRenderer extends UIComponent implements IListItemRenderer,
         throw new Error("Method not implemented.");
     }

-    public function get processedDescriptors():Boolean
+    /*public function get processedDescriptors():Boolean
     {
         throw new Error("Method not implemented.");
     }
@@ -321,7 +321,7 @@ public class ListItemRenderer extends UIComponent implements IListItemRenderer,
     public function set processedDescriptors(value:Boolean):void
     {
         throw new Error("Method not implemented.");
-    }
+    }*/

     public function get updateCompletePendingFlag():Boolean
     {
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
index 857004e..d0e56cf 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
@@ -39,6 +39,8 @@ import flash.events.IEventDispatcher;

 import mx.controls.beads.ToolTipBead;
 import mx.core.mx_internal;
+import mx.managers.IToolTipManagerClient;
+
 COMPILE::SWF
 {
 import flash.display.DisplayObject;
@@ -761,7 +763,7 @@ public class UIComponent extends UIBase
     IMXMLDocument,
     IInvalidating,
     IStatesObject,
-    ISimpleStyleClient,
+    ISimpleStyleClient,IToolTipManagerClient,
     IUIComponent, IVisualElement, IFlexModule, IValidatorListener
 {
     //--------------------------------------------------------------------------
@@ -1123,6 +1125,10 @@ public class UIComponent extends UIBase

         if (value)
         {
+            if (_needsLayout) {
+                //invalidateSize();
+                dispatchEvent(new Event('layoutNeeded'));
+            }
             dispatchEvent(new FlexEvent(FlexEvent.CREATION_COMPLETE));
         }
     }
@@ -2692,10 +2698,15 @@ COMPILE::JS
                     for (var i:int = 0; i < numChildren; i++)
                     {
                         var child:IUIComponent = getChildAt(i);
-                        if (child) // child is null for TextNodes
+                        //@todo investigate traces
+                        if (child is IUIComponent) // child is null for TextNodes
                             mw = Math.max(mw, child.getExplicitOrMeasuredWidth());
-                        else
-                            trace("Child class not IUIComponent: " + getQualifiedClassName(getElementAt(i)));
+                        else {
+                            if (child is IUIBase) {
+                                mw = Math.max(mw, child.width);
+                            }
+                            trace(getQualifiedClassName(this) + " Child class not IUIComponent: " + getQualifiedClassName(getElementAt(i)));
+                        }
                     }
                 }
                 if (oldWidth.length)
@@ -2768,10 +2779,15 @@ COMPILE::JS
                     for (var i:int = 0; i < numChildren; i++)
                     {
                         var child:IUIComponent = getChildAt(i);
-                        if (child)
+                        //@todo investigate traces
+                        if (child is IUIComponent) // child is null for TextNodes
                             mh = Math.max(mh, child.getExplicitOrMeasuredHeight());
-                        else
-                            trace("Child class not IUIComponent: " + getQualifiedClassName(getElementAt(i)));
+                        else {
+                            if (child is IUIBase) {
+                                mh = Math.max(mh, child.height);
+                            }
+                            trace(getQualifiedClassName(this) + " Child class not IUIComponent: " + getQualifiedClassName(getElementAt(i)));
+                        }
                     }
                 }
                 if (oldHeight.length)
@@ -4006,8 +4022,8 @@ COMPILE::JS
                         var n:int = arr.length;
                         var num:int = 0;
                         for (var i:int = 0; i < n; i++)
-                       {
-                               if ((arr[i] as WrappedHTMLElement).royale_wrapper)
+                       {   //@todo review issuses with internal native support that points to 'this' (2nd check below), can cause infinite recursion in measurement if avoided:
+                               if ((arr[i] as WrappedHTMLElement).royale_wrapper && (arr[i] as WrappedHTMLElement).royale_wrapper != this)
                                         num++;
                         }
                         return num;
@@ -4193,8 +4209,61 @@ COMPILE::JS
      */
     protected function initializationComplete():void
     {
-        dispatchEvent(new FlexEvent(FlexEvent.INITIALIZE));
-    }
+        processedDescriptors = true;
+    }
+
+        //----------------------------------
+        //  processedDescriptors
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the processedDescriptors property.
+         */
+        private var _processedDescriptors:Boolean = false;
+
+        [Inspectable(environment="none")]
+
+        /**
+         *  Set to <code>true</code> after immediate or deferred child creation,
+         *  depending on which one happens. For a Container object, it is set
+         *  to <code>true</code> at the end of
+         *  the <code>createComponentsFromDescriptors()</code> method,
+         *  meaning after the Container object creates its children from its child descriptors.
+         *
+         *  <p>For example, if an Accordion container uses deferred instantiation,
+         *  the <code>processedDescriptors</code> property for the second pane of
+         *  the Accordion container does not become <code>true</code> until after
+         *  the user navigates to that pane and the pane creates its children.
+         *  But, if the Accordion had set the <code>creationPolicy</code> property
+         *  to <code>"all"</code>, the <code>processedDescriptors</code> property
+         *  for its second pane is set to <code>true</code> during application startup.</p>
+         *
+         *  <p>For classes that are not containers, which do not have descriptors,
+         *  it is set to <code>true</code> after the <code>createChildren()</code>
+         *  method creates any internal component children.</p>
+         *
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get processedDescriptors():Boolean
+        {
+            return _processedDescriptors;
+        }
+
+        /**
+         *  @private
+         */
+        public function set processedDescriptors(value:Boolean):void
+        {
+            _processedDescriptors = value;
+
+            if (value)
+                dispatchEvent(new FlexEvent(FlexEvent.INITIALIZE));
+        }
+

     /**
      *  Create child objects of the component.
@@ -4221,9 +4290,17 @@ COMPILE::JS
      */
     protected function createChildren():void
     {
-        MXMLDataInterpreter.generateMXMLInstances(mxmlDocument, this, MXMLDescriptor);
+        var children:Array =  this.MXMLDescriptor;
+        if (children && children.length && !processedMXMLDescriptors) {
+            layoutDeferred = true;
+            MXMLDataInterpreter.generateMXMLInstances(mxmlDocument, this, children);
+            layoutDeferred = false;
+            processedMXMLDescriptors = true;
+        }
     }
-
+
+    private var processedMXMLDescriptors : Boolean;
+
     private var _mxmlDescriptor:Array;

     /**
@@ -4340,6 +4417,82 @@ COMPILE::JS
             (parent as IEventDispatcher).dispatchEvent(new Event("layoutNeeded")); // might cause too many layouts
     }

+    private var _layoutDeferred:Boolean;
+    /**
+     *  Support for deferred layout requests
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     * @productversion Royale 0.9.9
+     */
+    protected function get layoutDeferred():Boolean{
+        return _layoutDeferred
+    }
+    protected function set layoutDeferred(value:Boolean):void{
+        _layoutDeferred = value;
+        if (!value && _needsLayout) {
+            dispatchEvent(new Event('layoutNeeded'));
+        }
+    }
+    private var _needsLayout:Boolean;
+    /**
+     *  Support for deferred layout requests
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     * @productversion Royale 0.9.9
+     */
+    protected function get needsLayout():Boolean{
+        return _needsLayout;
+    }
+
+    /**
+     *  Support for deferred layout requests
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     * @productversion Royale 0.9.9
+     */
+    COMPILE::JS
+    override public function dispatchEvent(event:Object):Boolean{
+        //trap the layout requests and ignore them if we have deferred layout
+        if (event.type == "layoutNeeded" || event == 'layoutNeeded') {
+            if (_layoutDeferred) {
+                _needsLayout = true;
+                return false;
+            } else {
+                //layout will run, no 'need' to re-run later
+                _needsLayout = false;
+            }
+        }
+        return super.dispatchEvent(event);
+    }
+    /**
+     *  Support for deferred layout requests
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     * @productversion Royale 0.9.9
+     */
+    COMPILE::SWF
+    override public function dispatchEvent(event:Event):Boolean{
+        //trap the layout requests and ignore them if we have deferred layout
+        if (event.type == "layoutNeeded") {
+            if (_layoutDeferred) {
+                _needsLayout = true;
+                return false;
+            } else {
+                //layout will run, no 'need' to re-run later
+                _needsLayout = false;
+            }
+        }
+        return super.dispatchEvent(event);
+    }
+
     /**
      *  Helper method to invalidate parent size and display list if
      *  this object affects its layout (includeInLayout is true).
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Grid.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Grid.as
index 276c35a..e5170265 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Grid.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Grid.as
@@ -6022,13 +6022,13 @@ package spark.components
                         return 0;
                 }

-               public function set processedDescriptors(value:Boolean):void {
+               /*public function set processedDescriptors(value:Boolean):void {

                 }

                 public function get processedDescriptors():Boolean {
                         return false;
-               }
+               }*/

                 public function set updateCompletePendingFlag(value:Boolean):void {

diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SparkTextButtonItemRenderer.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SparkTextButtonItemRenderer.as
index b288837..ac67469 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SparkTextButtonItemRenderer.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SparkTextButtonItemRenderer.as
@@ -273,7 +273,7 @@ package spark.components.supportClasses
             throw new Error("Method not implemented.");
         }

-        public function get processedDescriptors():Boolean
+       /* public function get processedDescriptors():Boolean
         {
             throw new Error("Method not implemented.");
         }
@@ -281,7 +281,7 @@ package spark.components.supportClasses
         public function set processedDescriptors(value:Boolean):void
         {
             throw new Error("Method not implemented.");
-        }
+        }*/

         public function get updateCompletePendingFlag():Boolean
         {


[royale-asjs] 01/04: Prep for emulation creationPolicy: foundation for deferred layouts and

Posted by gr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gregdove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit 99d6bb9b556d98106bf69d8557078215914994ba
Author: greg-dove <gr...@gmail.com>
AuthorDate: Fri Dec 17 12:15:36 2021 +1300

    Prep for emulation creationPolicy: foundation for deferred layouts and
---
 .../AdvancedDataGridHeaderRenderer.as              |   4 +-
 .../dataGridClasses/DataGridHeaderRenderer.as      |   4 +-
 .../mx/controls/listClasses/ListItemRenderer.as    |   4 +-
 .../src/main/royale/mx/core/UIComponent.as         | 179 +++++++++++++++++++--
 .../src/main/royale/spark/components/Grid.as       |   4 +-
 .../supportClasses/SparkTextButtonItemRenderer.as  |   4 +-
 6 files changed, 176 insertions(+), 23 deletions(-)

diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/advancedDataGridClasses/AdvancedDataGridHeaderRenderer.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/advancedDataGridClasses/AdvancedDataGridHeaderRenderer.as
index 66c3989..074fa74 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/advancedDataGridClasses/AdvancedDataGridHeaderRenderer.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/advancedDataGridClasses/AdvancedDataGridHeaderRenderer.as
@@ -1012,7 +1012,7 @@ public class AdvancedDataGridHeaderRenderer extends UIComponent implements IData
     	throw new Error("Method not implemented.");
     }
 
-    public function get processedDescriptors():Boolean
+    /*public function get processedDescriptors():Boolean
     {
     	throw new Error("Method not implemented.");
     }
@@ -1020,7 +1020,7 @@ public class AdvancedDataGridHeaderRenderer extends UIComponent implements IData
     public function set processedDescriptors(value:Boolean):void
     {
     	throw new Error("Method not implemented.");
-    }
+    }*/
 
     public function get updateCompletePendingFlag():Boolean
     {
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/dataGridClasses/DataGridHeaderRenderer.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/dataGridClasses/DataGridHeaderRenderer.as
index 628abeb..f3d21e9 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/dataGridClasses/DataGridHeaderRenderer.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/dataGridClasses/DataGridHeaderRenderer.as
@@ -1010,7 +1010,7 @@ public class DataGridHeaderRenderer extends UIComponent implements IDataRenderer
     	throw new Error("Method not implemented.");
     }
 
-    public function get processedDescriptors():Boolean
+    /*public function get processedDescriptors():Boolean
     {
     	throw new Error("Method not implemented.");
     }
@@ -1018,7 +1018,7 @@ public class DataGridHeaderRenderer extends UIComponent implements IDataRenderer
     public function set processedDescriptors(value:Boolean):void
     {
     	throw new Error("Method not implemented.");
-    }
+    }*/
 
     public function get updateCompletePendingFlag():Boolean
     {
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListItemRenderer.as b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListItemRenderer.as
index 4412721..7116cc8 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListItemRenderer.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/controls/listClasses/ListItemRenderer.as
@@ -313,7 +313,7 @@ public class ListItemRenderer extends UIComponent implements IListItemRenderer,
     	throw new Error("Method not implemented.");
     }
 
-    public function get processedDescriptors():Boolean
+    /*public function get processedDescriptors():Boolean
     {
     	throw new Error("Method not implemented.");
     }
@@ -321,7 +321,7 @@ public class ListItemRenderer extends UIComponent implements IListItemRenderer,
     public function set processedDescriptors(value:Boolean):void
     {
     	throw new Error("Method not implemented.");
-    }
+    }*/
 
     public function get updateCompletePendingFlag():Boolean
     {
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
index 857004e..d0e56cf 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
@@ -39,6 +39,8 @@ import flash.events.IEventDispatcher;
 
 import mx.controls.beads.ToolTipBead;
 import mx.core.mx_internal;
+import mx.managers.IToolTipManagerClient;
+
 COMPILE::SWF
 {
 import flash.display.DisplayObject;
@@ -761,7 +763,7 @@ public class UIComponent extends UIBase
     IMXMLDocument,
     IInvalidating,
     IStatesObject,
-    ISimpleStyleClient,
+    ISimpleStyleClient,IToolTipManagerClient,
     IUIComponent, IVisualElement, IFlexModule, IValidatorListener
 {
     //--------------------------------------------------------------------------
@@ -1123,6 +1125,10 @@ public class UIComponent extends UIBase
 
         if (value)
         {
+            if (_needsLayout) {
+                //invalidateSize();
+                dispatchEvent(new Event('layoutNeeded'));
+            }
             dispatchEvent(new FlexEvent(FlexEvent.CREATION_COMPLETE));
         }
     }
@@ -2692,10 +2698,15 @@ COMPILE::JS
                     for (var i:int = 0; i < numChildren; i++)
                     {
                         var child:IUIComponent = getChildAt(i);
-                        if (child) // child is null for TextNodes
+                        //@todo investigate traces
+                        if (child is IUIComponent) // child is null for TextNodes
                             mw = Math.max(mw, child.getExplicitOrMeasuredWidth());
-                        else
-                            trace("Child class not IUIComponent: " + getQualifiedClassName(getElementAt(i)));
+                        else {
+                            if (child is IUIBase) {
+                                mw = Math.max(mw, child.width);
+                            }
+                            trace(getQualifiedClassName(this) + " Child class not IUIComponent: " + getQualifiedClassName(getElementAt(i)));
+                        }
                     }
                 }
                 if (oldWidth.length)
@@ -2768,10 +2779,15 @@ COMPILE::JS
                     for (var i:int = 0; i < numChildren; i++)
                     {
                         var child:IUIComponent = getChildAt(i);
-                        if (child)
+                        //@todo investigate traces
+                        if (child is IUIComponent) // child is null for TextNodes
                             mh = Math.max(mh, child.getExplicitOrMeasuredHeight());
-                        else
-                            trace("Child class not IUIComponent: " + getQualifiedClassName(getElementAt(i)));
+                        else {
+                            if (child is IUIBase) {
+                                mh = Math.max(mh, child.height);
+                            }
+                            trace(getQualifiedClassName(this) + " Child class not IUIComponent: " + getQualifiedClassName(getElementAt(i)));
+                        }
                     }
                 }
                 if (oldHeight.length)
@@ -4006,8 +4022,8 @@ COMPILE::JS
 			var n:int = arr.length;
 			var num:int = 0;
 			for (var i:int = 0; i < n; i++)
-			{
-				if ((arr[i] as WrappedHTMLElement).royale_wrapper)
+			{   //@todo review issuses with internal native support that points to 'this' (2nd check below), can cause infinite recursion in measurement if avoided:
+				if ((arr[i] as WrappedHTMLElement).royale_wrapper && (arr[i] as WrappedHTMLElement).royale_wrapper != this)
 					num++;
 			}
 			return num;
@@ -4193,8 +4209,61 @@ COMPILE::JS
      */
     protected function initializationComplete():void
     {
-        dispatchEvent(new FlexEvent(FlexEvent.INITIALIZE));
-    }
+        processedDescriptors = true;
+    }
+
+        //----------------------------------
+        //  processedDescriptors
+        //----------------------------------
+
+        /**
+         *  @private
+         *  Storage for the processedDescriptors property.
+         */
+        private var _processedDescriptors:Boolean = false;
+
+        [Inspectable(environment="none")]
+
+        /**
+         *  Set to <code>true</code> after immediate or deferred child creation,
+         *  depending on which one happens. For a Container object, it is set
+         *  to <code>true</code> at the end of
+         *  the <code>createComponentsFromDescriptors()</code> method,
+         *  meaning after the Container object creates its children from its child descriptors.
+         *
+         *  <p>For example, if an Accordion container uses deferred instantiation,
+         *  the <code>processedDescriptors</code> property for the second pane of
+         *  the Accordion container does not become <code>true</code> until after
+         *  the user navigates to that pane and the pane creates its children.
+         *  But, if the Accordion had set the <code>creationPolicy</code> property
+         *  to <code>"all"</code>, the <code>processedDescriptors</code> property
+         *  for its second pane is set to <code>true</code> during application startup.</p>
+         *
+         *  <p>For classes that are not containers, which do not have descriptors,
+         *  it is set to <code>true</code> after the <code>createChildren()</code>
+         *  method creates any internal component children.</p>
+         *
+         *  @langversion 3.0
+         *  @playerversion Flash 9
+         *  @playerversion AIR 1.1
+         *  @productversion Flex 3
+         */
+        public function get processedDescriptors():Boolean
+        {
+            return _processedDescriptors;
+        }
+
+        /**
+         *  @private
+         */
+        public function set processedDescriptors(value:Boolean):void
+        {
+            _processedDescriptors = value;
+
+            if (value)
+                dispatchEvent(new FlexEvent(FlexEvent.INITIALIZE));
+        }
+
     
     /**
      *  Create child objects of the component.
@@ -4221,9 +4290,17 @@ COMPILE::JS
      */
     protected function createChildren():void
     {
-        MXMLDataInterpreter.generateMXMLInstances(mxmlDocument, this, MXMLDescriptor);
+        var children:Array =  this.MXMLDescriptor;
+        if (children && children.length && !processedMXMLDescriptors) {
+            layoutDeferred = true;
+            MXMLDataInterpreter.generateMXMLInstances(mxmlDocument, this, children);
+            layoutDeferred = false;
+            processedMXMLDescriptors = true;
+        }
     }
-    
+
+    private var processedMXMLDescriptors : Boolean;
+
     private var _mxmlDescriptor:Array;
     
     /**
@@ -4340,6 +4417,82 @@ COMPILE::JS
             (parent as IEventDispatcher).dispatchEvent(new Event("layoutNeeded")); // might cause too many layouts
     }
 
+    private var _layoutDeferred:Boolean;
+    /**
+     *  Support for deferred layout requests
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     * @productversion Royale 0.9.9
+     */
+    protected function get layoutDeferred():Boolean{
+        return _layoutDeferred
+    }
+    protected function set layoutDeferred(value:Boolean):void{
+        _layoutDeferred = value;
+        if (!value && _needsLayout) {
+            dispatchEvent(new Event('layoutNeeded'));
+        }
+    }
+    private var _needsLayout:Boolean;
+    /**
+     *  Support for deferred layout requests
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     * @productversion Royale 0.9.9
+     */
+    protected function get needsLayout():Boolean{
+        return _needsLayout;
+    }
+
+    /**
+     *  Support for deferred layout requests
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     * @productversion Royale 0.9.9
+     */
+    COMPILE::JS
+    override public function dispatchEvent(event:Object):Boolean{
+        //trap the layout requests and ignore them if we have deferred layout
+        if (event.type == "layoutNeeded" || event == 'layoutNeeded') {
+            if (_layoutDeferred) {
+                _needsLayout = true;
+                return false;
+            } else {
+                //layout will run, no 'need' to re-run later
+                _needsLayout = false;
+            }
+        }
+        return super.dispatchEvent(event);
+    }
+    /**
+     *  Support for deferred layout requests
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     * @productversion Royale 0.9.9
+     */
+    COMPILE::SWF
+    override public function dispatchEvent(event:Event):Boolean{
+        //trap the layout requests and ignore them if we have deferred layout
+        if (event.type == "layoutNeeded") {
+            if (_layoutDeferred) {
+                _needsLayout = true;
+                return false;
+            } else {
+                //layout will run, no 'need' to re-run later
+                _needsLayout = false;
+            }
+        }
+        return super.dispatchEvent(event);
+    }
+
     /**
      *  Helper method to invalidate parent size and display list if
      *  this object affects its layout (includeInLayout is true).
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Grid.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Grid.as
index 276c35a..e5170265 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Grid.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/Grid.as
@@ -6022,13 +6022,13 @@ package spark.components
 			return 0;
 		}
 		
-		public function set processedDescriptors(value:Boolean):void {
+		/*public function set processedDescriptors(value:Boolean):void {
 			
 		}
 		
 		public function get processedDescriptors():Boolean {
 			return false;
-		}
+		}*/
 		
 		public function set updateCompletePendingFlag(value:Boolean):void {
 			
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SparkTextButtonItemRenderer.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SparkTextButtonItemRenderer.as
index b288837..ac67469 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SparkTextButtonItemRenderer.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/SparkTextButtonItemRenderer.as
@@ -273,7 +273,7 @@ package spark.components.supportClasses
             throw new Error("Method not implemented.");
         }
 
-        public function get processedDescriptors():Boolean
+       /* public function get processedDescriptors():Boolean
         {
             throw new Error("Method not implemented.");
         }
@@ -281,7 +281,7 @@ package spark.components.supportClasses
         public function set processedDescriptors(value:Boolean):void
         {
             throw new Error("Method not implemented.");
-        }
+        }*/
 
         public function get updateCompletePendingFlag():Boolean
         {