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 <[email protected]> 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
