//////////////////////////////////////////////////////////////////////////////// // // 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.states { import mx.binding.BindingManager; import mx.core.UIComponent; import mx.core.mx_internal; import mx.events.PropertyChangeEvent; import mx.utils.OnDemandEventDispatcher; /** * The OverrideBase class is the base class for the * override classes used by view states. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class OverrideBase extends OnDemandEventDispatcher implements IOverride { //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function OverrideBase() {} //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- /** * @private * Flag which tracks if we're actively overriding a property. */ protected var applied:Boolean = false; /** * @private * Our most recent parent context. */ protected var parentContext:UIComponent; /** * @private */ private var targetProperty:String; /** * @private * Specifies whether or not a property-centric * state override's base value is data bound. * * This value is intended for use by the MXML * compiler only. */ public var isBaseValueDataBound:Boolean; //-------------------------------------------------------------------------- // // Methods // //-------------------------------------------------------------------------- /** * IOverride interface method; this class implements it as an empty method. * * @copy IOverride#initialize() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function initialize():void {} /** * @inheritDoc * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function apply(parent:UIComponent):void {} /** * @inheritDoc * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function remove(parent:UIComponent):void {} /** * @private * Initialize this object from a descriptor. */ public function initializeFromObject(properties:Object):Object { for (var p:String in properties) { this[p] = properties[p]; } return Object(this); } /** * @private * @param parent The document level context for this override. * @param target The component level context for this override. */ protected function getOverrideContext(target:Object, parent:UIComponent):Object { if (target == null) return parent; if (target is String) return parent[target]; return target; } /** * @private * If the target of our override is a String (representing a property), * we register a PROPERTY_CHANGE listener to determine when/if our target * context becomes available or changes. */ protected function addContextListener(target:Object):void { if (target is String && parentContext != null) { targetProperty = target as String; parentContext.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, context_propertyChangeHandler); } } /** * @private * Unregister our PROPERTY_CHANGE listener. */ protected function removeContextListener():void { if (parentContext != null) { parentContext.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE, context_propertyChangeHandler); } } /** * @private * Called when our target context is set. We re-apply our override * if appropriate. */ protected function context_propertyChangeHandler(event:PropertyChangeEvent):void { if (event.property == targetProperty && event.newValue != null) { apply(parentContext); removeContextListener(); } } /** * @private * Disables or enables binding associated with a property override. */ protected function enableBindings(target:Object, parent:UIComponent, property:String, enable:Boolean=true):void { if (isBaseValueDataBound && target && parent && property) { var document:Object = target.hasOwnProperty("document") ? target.document : null; document = !document && parent.hasOwnProperty("document") ? parent.document : document; var name:String = target.hasOwnProperty("id") ? target.id : null; name = !name && target.hasOwnProperty("name") ? target.name : name; if (document && name) { var root:String = (document == target) ? "this" : name; BindingManager.enableBindings(document, root + "." + property, enable); } } } } }