import * as kiwi from '@lume/kiwi' ; import Attribute from './Attribute.js' ; import Relation from './Relation.js' ; import SubView from './SubView.js' ; const defaultPriorityStrength = kiwi . Strength . create ( 0 , 1000 , 1000 ) ; module class View { declare _solver : kiwi . Solver ; declare _subViews : { } ; declare _parentSubView : SubView ; declare _spacing ? : number | number [ ] ; declare _spacingVars ? : kiwi . Variable [ ] ; declare _spacingExpr ? : kiwi . Expression [ ] ; class param options param { Number } options . width param { Number } options . height param { Number | Object } options . spacing param { Array } options . constraints constructor ( options ) { this . _solver = new kiwi . Solver ( ) ; this . _subViews = { } ; this . _parentSubView = new SubView ( { solver : this . _solver , } ) ; this . setSpacing ( options && options . spacing !== undefined ? options . spacing : 8 ) ; if ( options ) { if ( options . width !== undefined || options . height !== undefined ) { this . setSize ( options . width , options . height ) ; } if ( options . constraints ) { this . addConstraints ( options . constraints ) ; } } } param { Number } width param { Number } height return { View } setSize ( width , height ) { this . _parentSubView . intrinsicWidth = width ; this . _parentSubView . intrinsicHeight = height ; return this ; } readonly type { Number } get width ( ) { return this . _parentSubView . intrinsicWidth ; } readonly type { Number } get height ( ) { return this . _parentSubView . intrinsicHeight ; } readonly type { Number } get fittingWidth ( ) { return this . _parentSubView . width ; } readonly type { Number } get fittingHeight ( ) { return this . _parentSubView . height ; } param { Number | Array } spacing return { View } setSpacing ( spacing ) { if ( ! Array . isArray ( spacing ) ) { spacing = [ spacing , spacing , spacing , spacing , spacing , spacing , 1 ] ; } else { switch ( spacing . length ) { case 1 : spacing = [ spacing [ 0 ] , spacing [ 0 ] , spacing [ 0 ] , spacing [ 0 ] , spacing [ 0 ] , spacing [ 0 ] , 1 ] ; break ; case 2 : spacing = [ spacing [ 1 ] , spacing [ 0 ] , spacing [ 1 ] , spacing [ 0 ] , spacing [ 0 ] , spacing [ 1 ] , 1 ] ; break ; case 3 : spacing = [ spacing [ 1 ] , spacing [ 0 ] , spacing [ 1 ] , spacing [ 0 ] , spacing [ 0 ] , spacing [ 1 ] , spacing [ 2 ] ] ; break ; case 6 : spacing = [ spacing [ 0 ] , spacing [ 1 ] , spacing [ 2 ] , spacing [ 3 ] , spacing [ 4 ] , spacing [ 5 ] , 1 ] ; break ; case 7 : break ; default : throw 'Invalid spacing syntax' ; } } if ( ! this . _compareSpacing ( this . _spacing , spacing ) ) { this . _spacing = spacing ; if ( this . _spacingVars ) { for ( var i = 0 ; i < this . _spacingVars . length ; i ++ ) { if ( this . _spacingVars [ i ] ) { this . _solver . suggestValue ( this . _spacingVars [ i ] , this . _spacing ! [ i ] ) ; } } this . _solver . updateVariables ( ) ; } } return this ; } _compareSpacing ( old , newz ) { if ( old === newz ) { return true ; } if ( ! old || ! newz ) { return false ; } for ( var i = 0 ; i < 7 ; i ++ ) { if ( old [ i ] !== newz [ i ] ) { return false ; } } return true ; } param { Object } constraint return { View } addConstraint ( constraint ) { this . _addConstraint ( constraint ) ; this . _solver . updateVariables ( ) ; return this ; } param { Array } constraints return { View } addConstraints ( constraints ) { for ( var j = 0 ; j < constraints . length ; j ++ ) { this . _addConstraint ( constraints [ j ] ) ; } this . _solver . updateVariables ( ) ; return this ; } _addConstraint ( constraint ) { let relation ; const multiplier = constraint . multiplier !== undefined ? constraint . multiplier : 1 ; let constant = constraint . constant !== undefined ? constraint . constant : 0 ; if ( constant === 'default' ) { constant = this . _getSpacing ( constraint ) ; } const attr1 = this . _getSubView ( constraint . view1 ) . _getAttr ( constraint . attr1 ) ; let attr2 ; if ( constraint . attr2 === Attribute . CONST ) { attr2 = this . _getConst ( undefined , constraint . constant ) ; } else { attr2 = this . _getSubView ( constraint . view2 ) . _getAttr ( constraint . attr2 ) ; if ( multiplier !== 1 && constant ) { attr2 = attr2 . multiply ( multiplier ) . plus ( constant ) ; } else if ( constant ) { attr2 = attr2 . plus ( constant ) ; } else if ( multiplier !== 1 ) { attr2 = attr2 . multiply ( multiplier ) ; } } const strength = constraint . priority !== undefined && constraint . priority < 1000 ? kiwi . Strength . create ( 0 , constraint . priority , 1000 ) : defaultPriorityStrength ; switch ( constraint . relation ) { case Relation . EQU : relation = new kiwi . Constraint ( attr1 , kiwi . Operator . Eq , attr2 , strength ) ; break ; case Relation . GEQ : relation = new kiwi . Constraint ( attr1 , kiwi . Operator . Ge , attr2 , strength ) ; break ; case Relation . LEQ : relation = new kiwi . Constraint ( attr1 , kiwi . Operator . Le , attr2 , strength ) ; break ; default : throw 'Invalid relation specified: ' + constraint . relation ; } this . _solver . addConstraint ( relation ) ; } _getSpacing ( constraint ) { let index = 4 ; if ( ! constraint . view1 && constraint . attr1 === 'left' ) { index = 3 ; } else if ( ! constraint . view1 && constraint . attr1 === 'top' ) { index = 0 ; } else if ( ! constraint . view2 && constraint . attr2 === 'right' ) { index = 1 ; } else if ( ! constraint . view2 && constraint . attr2 === 'bottom' ) { index = 2 ; } else { switch ( constraint . attr1 ) { case 'left' : case 'right' : case 'centerX' : case 'leading' : case 'trailing' : index = 4 ; break ; case 'zIndex' : index = 6 ; break ; default : index = 5 ; } } this . _spacingVars = this . _spacingVars || new Array ( 7 ) ; this . _spacingExpr = this . _spacingExpr || new Array ( 7 ) ; if ( ! this . _spacingVars [ index ] ) { this . _spacingVars [ index ] = new kiwi . Variable ( ) ; this . _solver . addEditVariable ( this . _spacingVars [ index ] , kiwi . Strength . create ( 999 , 1000 , 1000 ) ) ; this . _spacingExpr [ index ] = this . _spacingVars [ index ] . multiply ( - 1 ) ; this . _solver . suggestValue ( this . _spacingVars [ index ] , this . _spacing ! [ index ] ) ; } return this . _spacingExpr [ index ] ; } _getSubView ( viewName ) { if ( ! viewName ) { return this . _parentSubView ; } else if ( viewName . name ) { this . _subViews [ viewName . name ] = this . _subViews [ viewName . name ] || new SubView ( { name : viewName . name , solver : this . _solver , } ) ; this . _subViews [ viewName . name ] . _type = this . _subViews [ viewName . name ] . _type || viewName . type ; return this . _subViews [ viewName . name ] ; } else { this . _subViews [ viewName ] = this . _subViews [ viewName ] || new SubView ( { name : viewName , solver : this . _solver , } ) ; return this . _subViews [ viewName ] ; } } _getConst ( name , value ) { const vr = new kiwi . Variable ( ) ; this . _solver . addConstraint ( new kiwi . Constraint ( vr , kiwi . Operator . Eq , value ) ) ; return vr ; } readonly type { Object . SubView } get subViews ( ) { return this . _subViews ; } } export default View ;