import { View , CSSType } from '../core/view' ; import { LayoutBase } from '../layouts/layout-base' ; import { Property } from '../core/properties' ; import { Trace } from '../../trace' ; /**
 * Proxy view container that adds all its native children directly to the parent.
 * To be used as a logical grouping container of views.
 */ @ CSSType ( 'ProxyViewContainer' ) export class ProxyViewContainer extends LayoutBase { private proxiedLayoutProperties = new Set < string > ( ) ; constructor ( ) { super ( ) ; this . nativeViewProtected = undefined ; } get ios ( ) : any { return null ; } get android ( ) : any { return null ; } get isLayoutRequested ( ) : boolean { return false ; } public createNativeView ( ) { return undefined ; } public _getNativeViewsCount ( ) { let result = 0 ; this . eachChildView ( ( cv ) => { result += cv . _getNativeViewsCount ( ) ; return true ; } ) ; return result ; } public _eachLayoutView ( callback ) { this . eachChildView ( ( cv ) => { if ( ! cv . isCollapsed ) { cv . _eachLayoutView ( callback ) ; } return true ; } ) ; } public _addViewToNativeVisualTree ( child , atIndex ? ) { if ( Trace . isEnabled ( ) ) { Trace . write ( 'ProxyViewContainer._addViewToNativeVisualTree for a child ' + child + ' ViewContainer.parent: ' + this . parent , Trace . categories . ViewHierarchy ) ; } super . _addViewToNativeVisualTree ( child ) ; layoutProperties . forEach ( ( propName ) => { const proxyPropName = makeProxyPropName ( propName ) ; child [ proxyPropName ] = child [ propName ] ; if ( this . proxiedLayoutProperties . has ( propName ) ) { this . _applyLayoutPropertyToChild ( child , propName , this [ propName ] ) ; } } ) ; const parent = this . parent ; if ( parent instanceof View ) { let baseIndex = 0 ; let insideIndex = 0 ; if ( parent instanceof LayoutBase ) { baseIndex = parent . _childIndexToNativeChildIndex ( parent . getChildIndex ( this ) ) ; } if ( atIndex !== undefined ) { insideIndex = this . _childIndexToNativeChildIndex ( atIndex ) ; } else { insideIndex = this . _getNativeViewsCount ( ) ; } if ( Trace . isEnabled ( ) ) { Trace . write ( 'ProxyViewContainer._addViewToNativeVisualTree at: ' + atIndex + ' base: ' + baseIndex + ' additional: ' + insideIndex , Trace . categories . ViewHierarchy ) ; } return parent . _addViewToNativeVisualTree ( child , baseIndex + insideIndex ) ; } return false ; } public _removeViewFromNativeVisualTree ( child ) { if ( Trace . isEnabled ( ) ) { Trace . write ( 'ProxyViewContainer._removeViewFromNativeVisualTree for a child ' + child + ' ViewContainer.parent: ' + this . parent , Trace . categories . ViewHierarchy ) ; } super . _removeViewFromNativeVisualTree ( child ) ; const parent = this . parent ; if ( parent instanceof View ) { return parent . _removeViewFromNativeVisualTree ( child ) ; } } public _registerLayoutChild ( child ) { const parent = this . parent ; if ( parent instanceof LayoutBase ) { parent . _registerLayoutChild ( child ) ; } } public _unregisterLayoutChild ( child ) { const parent = this . parent ; if ( parent instanceof LayoutBase ) { parent . _unregisterLayoutChild ( child ) ; } } public _parentChanged ( oldParent ) { super . _parentChanged ( oldParent ) ; const addingToParent = this . parent && ! oldParent ; const newLayout = < LayoutBase > this . parent ; const oldLayout = < LayoutBase > oldParent ; if ( addingToParent && newLayout instanceof LayoutBase ) { this . eachLayoutChild ( ( child ) => { newLayout . _registerLayoutChild ( child ) ; return true ; } ) ; } else if ( oldLayout instanceof LayoutBase ) { this . eachLayoutChild ( ( child ) => { oldLayout . _unregisterLayoutChild ( child ) ; return true ; } ) ; } } /**
     * Layout property changed, proxy the new value to the child view(s)
     */ public _changedLayoutProperty ( propName , value ) { const numChildren = this . _getNativeViewsCount ( ) ; if ( numChildren > 1 ) { Trace . write ( "ProxyViewContainer._changeLayoutProperty - you're setting '" + propName + "' for " + this + ' with more than one child. Probably this is not what you want, consider wrapping it in a StackLayout ' , Trace . categories . ViewHierarchy , Trace . messageType . error ) ; } this . eachLayoutChild ( ( child ) => { this . _applyLayoutPropertyToChild ( child , propName , value ) ; return true ; } ) ; this . proxiedLayoutProperties . add ( propName ) ; } /**
     * Apply the layout property to the child view.
     */ private _applyLayoutPropertyToChild ( child , propName , value ) { const proxyPropName = makeProxyPropName ( propName ) ; if ( proxyPropName in child ) { if ( child [ propName ] !== child [ proxyPropName ] ) { if ( Trace . isEnabled ( ) ) { Trace . write ( 'ProxyViewContainer._applyLayoutPropertyToChild child ' + child + ' has its own value [' + child [ propName ] + '] for [' + propName + ']' , Trace . categories . ViewHierarchy ) ; } return ; } } child [ propName ] = value ; child [ proxyPropName ] = value ; } } const layoutProperties = [ 'left' , 'top' , 'dock' , 'flexDirection' , 'flexWrap' , 'justifyContent' , 'alignItems' , 'alignContent' , 'order' , 'flexGrow' , 'flexShrink' , 'flexWrapBefore' , 'alignSelf' , 'flexFlow' , 'flex' , 'column' , 'columnSpan' , 'col' , 'colSpan' , 'row' , 'rowSpan' , ] ; for ( const name of layoutProperties ) { const proxyProperty = new Property < ProxyViewContainer , string > ( { name , valueChanged ( target , oldValue , value ) { target . _changedLayoutProperty ( name , value ) ; } , } ) ; proxyProperty . register ( ProxyViewContainer ) ; } function makeProxyPropName ( propName ) { return `_proxy:${ propName }` ; }