import { Nullable } from "babylonjs/types" ; import { Observable , Observer } from "babylonjs/Misc/observable" ; import { Vector2 , Vector3 , Matrix } from "babylonjs/Maths/math.vector" ; import { PointerEventTypes , PointerInfoBase } from "babylonjs/Events/pointerEvents" ; import { Logger } from "babylonjs/Misc/logger" ; import { Tools } from "babylonjs/Misc/tools" ; import { TransformNode } from "babylonjs/Meshes/transformNode" ; import { Scene } from "babylonjs/scene" ; import { Container } from "./container" ; import { AdvancedDynamicTexture } from "../advancedDynamicTexture" ; import { ValueAndUnit } from "../valueAndUnit" ; import { Measure } from "../measure" ; import { Style } from "../style" ; import { Matrix2D , Vector2WithInfo } from "../math2D" ; import { RegisterClass } from "babylonjs/Misc/typeStore" ; import { SerializationHelper , serialize } from "babylonjs/Misc/decorators" ; import { ICanvasRenderingContext } from "babylonjs/Engines/ICanvas" ; import { Engine } from "babylonjs/Engines/engine" ; see https export class Control { /**
     * Gets or sets a boolean indicating if alpha must be an inherited value (false by default)
     */ public static AllowAlphaInheritance = false ; private _alpha = 1 ; private _alphaSet = false ; private _zIndex = 0 ; hidden public _host : AdvancedDynamicTexture ; /** Gets or sets the control parent */ public parent : Nullable < Container > ; hidden public _currentMeasure = Measure . Empty ( ) ; hidden public _tempPaddingMeasure = Measure . Empty ( ) ; private _fontFamily = "Arial" ; private _fontStyle = "" ; private _fontWeight = "" ; private _fontSize = new ValueAndUnit ( 18 , ValueAndUnit . UNITMODE_PIXEL , false ) ; private _font : string ; hidden public _width = new ValueAndUnit ( 1 , ValueAndUnit . UNITMODE_PERCENTAGE , false ) ; hidden public _height = new ValueAndUnit ( 1 , ValueAndUnit . UNITMODE_PERCENTAGE , false ) ; hidden protected _fontOffset : { ascent : number ; height : number ; descent : number ; } ; private _color = "" ; private _style : Nullable < Style > = null ; private _styleObserver : Nullable < Observer < Style > > ; hidden protected _horizontalAlignment = Control . HORIZONTAL_ALIGNMENT_CENTER ; hidden protected _verticalAlignment = Control . VERTICAL_ALIGNMENT_CENTER ; hidden protected _isDirty = true ; hidden protected _wasDirty = false ; hidden public _tempParentMeasure = Measure . Empty ( ) ; hidden public _prevCurrentMeasureTransformedIntoGlobalSpace = Measure . Empty ( ) ; hidden protected _cachedParentMeasure = Measure . Empty ( ) ; private _descendantsOnlyPadding = false ; private _paddingLeft = new ValueAndUnit ( 0 ) ; private _paddingRight = new ValueAndUnit ( 0 ) ; private _paddingTop = new ValueAndUnit ( 0 ) ; private _paddingBottom = new ValueAndUnit ( 0 ) ; hidden public _left = new ValueAndUnit ( 0 ) ; hidden public _top = new ValueAndUnit ( 0 ) ; private _scaleX = 1.0 ; private _scaleY = 1.0 ; private _rotation = 0 ; private _transformCenterX = 0.5 ; private _transformCenterY = 0.5 ; hidden public _transformMatrix = Matrix2D . Identity ( ) ; hidden protected _invertTransformMatrix = Matrix2D . Identity ( ) ; hidden protected _transformedPosition = Vector2 . Zero ( ) ; private _isMatrixDirty = true ; private _cachedOffsetX : number ; private _cachedOffsetY : number ; private _isVisible = true ; private _isHighlighted = false ; private _highlightColor = "#4affff" ; protected _highlightLineWidth = 2 ; hidden public _linkedMesh : Nullable < TransformNode > ; private _fontSet = false ; private _dummyVector2 = Vector2 . Zero ( ) ; private _downCount = 0 ; private _enterCount = - 1 ; private _doNotRender = false ; private _downPointerIds : { [ id ] : boolean ; } = { } ; private _evaluatedMeasure = new Measure ( 0 , 0 , 0 , 0 ) ; private _evaluatedParentMeasure = new Measure ( 0 , 0 , 0 , 0 ) ; protected _isEnabled = true ; protected _disabledColor = "#9a9a9a" ; protected _disabledColorItem = "#6a6a6a" ; protected _isReadOnly = false ; hidden protected _rebuildLayout = false ; hidden public _customData : any = { } ; hidden public _isClipped = false ; hidden public _automaticSize = false ; hidden public _tag : any ; /**
     * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
     */ public uniqueId : number ; /**
     * Gets or sets a boolean indicating if the control is readonly (default: false).
     * A readonly control will still raise pointer events but will not react to them
     */ public get isReadOnly ( ) { return this . _isReadOnly ; } public set isReadOnly ( value ) { this . _isReadOnly = value ; } /**
     * Gets the transformed measure, that is the bounding box of the control after applying all transformations
     */ public get transformedMeasure ( ) : Measure { return this . _evaluatedMeasure ; } /**
     * Gets or sets an object used to store user defined information for the node
     */ @ serialize ( ) public metadata : any = null ; /** Gets or sets a boolean indicating if the control can be hit with pointer events */ @ serialize ( ) public isHitTestVisible = true ; /** Gets or sets a boolean indicating if the control can block pointer events */ @ serialize ( ) public isPointerBlocker = false ; /** Gets or sets a boolean indicating if the control can be focusable */ @ serialize ( ) public isFocusInvisible = false ; /**
     * Gets or sets a boolean indicating if the children are clipped to the current control bounds.
     * Please note that not clipping children may generate issues with adt.useInvalidateRectOptimization so it is recommended to turn this optimization off if you want to use unclipped children
     */ @ serialize ( ) public clipChildren = true ; /**
     * Gets or sets a boolean indicating that control content must be clipped
     * Please note that not clipping children may generate issues with adt.useInvalidateRectOptimization so it is recommended to turn this optimization off if you want to use unclipped children
     */ @ serialize ( ) public clipContent = true ; /**
     * Gets or sets a boolean indicating that the current control should cache its rendering (useful when the control does not change often)
     */ @ serialize ( ) public useBitmapCache = false ; private _cacheData : Nullable < ImageData > ; private _shadowOffsetX = 0 ; /** Gets or sets a value indicating the offset to apply on X axis to render the shadow */ @ serialize ( ) public get shadowOffsetX ( ) { return this . _shadowOffsetX ; } public set shadowOffsetX ( value ) { if ( this . _shadowOffsetX === value ) { return ; } this . _shadowOffsetX = value ; this . _markAsDirty ( ) ; } private _shadowOffsetY = 0 ; /** Gets or sets a value indicating the offset to apply on Y axis to render the shadow */ @ serialize ( ) public get shadowOffsetY ( ) { return this . _shadowOffsetY ; } public set shadowOffsetY ( value ) { if ( this . _shadowOffsetY === value ) { return ; } this . _shadowOffsetY = value ; this . _markAsDirty ( ) ; } private _shadowBlur = 0 ; private _previousShadowBlur = 0 ; /** Gets or sets a value indicating the amount of blur to use to render the shadow */ @ serialize ( ) public get shadowBlur ( ) { return this . _shadowBlur ; } public set shadowBlur ( value ) { if ( this . _shadowBlur === value ) { return ; } this . _previousShadowBlur = this . _shadowBlur ; this . _shadowBlur = value ; this . _markAsDirty ( ) ; } private _shadowColor = "black" ; /** Gets or sets a value indicating the color of the shadow (black by default ie. "#000") */ @ serialize ( ) public get shadowColor ( ) { return this . _shadowColor ; } public set shadowColor ( value ) { if ( this . _shadowColor === value ) { return ; } this . _shadowColor = value ; this . _markAsDirty ( ) ; } /** Gets or sets the cursor to use when the control is hovered */ @ serialize ( ) public hoverCursor = "" ; hidden protected _linkOffsetX = new ValueAndUnit ( 0 ) ; hidden protected _linkOffsetY = new ValueAndUnit ( 0 ) ; /** Gets the control type name */ public get typeName ( ) : string { return this . _getTypeName ( ) ; } returns public getClassName ( ) { return this . _getTypeName ( ) ; } /**
     * An event triggered when pointer wheel is scrolled
     */ public onWheelObservable = new Observable < Vector2 > ( ) ; /**
     * An event triggered when the pointer moves over the control.
     */ public onPointerMoveObservable = new Observable < Vector2 > ( ) ; /**
     * An event triggered when the pointer moves out of the control.
     */ public onPointerOutObservable = new Observable < Control > ( ) ; /**
     * An event triggered when the pointer taps the control
     */ public onPointerDownObservable = new Observable < Vector2WithInfo > ( ) ; /**
     * An event triggered when pointer up
     */ public onPointerUpObservable = new Observable < Vector2WithInfo > ( ) ; /**
     * An event triggered when a control is clicked on
     */ public onPointerClickObservable = new Observable < Vector2WithInfo > ( ) ; /**
     * An event triggered when pointer enters the control
     */ public onPointerEnterObservable = new Observable < Control > ( ) ; /**
     * An event triggered when the control is marked as dirty
     */ public onDirtyObservable = new Observable < Control > ( ) ; /**
     * An event triggered before drawing the control
     */ public onBeforeDrawObservable = new Observable < Control > ( ) ; /**
     * An event triggered after the control was drawn
     */ public onAfterDrawObservable = new Observable < Control > ( ) ; /**
     * An event triggered when the control has been disposed
     */ public onDisposeObservable = new Observable < Control > ( ) ; /**
     * Get the hosting AdvancedDynamicTexture
     */ public get host ( ) : AdvancedDynamicTexture { return this . _host ; } /** Gets or set information about font offsets (used to render and align text) */ @ serialize ( ) public get fontOffset ( ) : { ascent : number ; height : number ; descent : number ; } { return this . _fontOffset ; } public set fontOffset ( offset ) { this . _fontOffset = offset ; } /** Gets or sets alpha value for the control (1 means opaque and 0 means entirely transparent) */ @ serialize ( ) public get alpha ( ) : number { return this . _alpha ; } public set alpha ( value ) { if ( this . _alpha === value ) { return ; } this . _alphaSet = true ; this . _alpha = value ; this . _markAsDirty ( ) ; } /**
     * Gets or sets a number indicating size of stroke we want to highlight the control with (mostly for debugging purpose)
     */ public get highlightLineWidth ( ) : number { return this . _highlightLineWidth ; } public set highlightLineWidth ( value ) { if ( this . _highlightLineWidth === value ) { return ; } this . _highlightLineWidth = value ; this . _markAsDirty ( ) ; } /**
     * Gets or sets a boolean indicating that we want to highlight the control (mostly for debugging purpose)
     */ public get isHighlighted ( ) : boolean { return this . _isHighlighted ; } public set isHighlighted ( value ) { if ( this . _isHighlighted === value ) { return ; } this . _isHighlighted = value ; this . _markAsDirty ( ) ; } /**
     * Gets or sets a string defining the color to use for highlighting this control
     */ public get highlightColor ( ) : string { return this . _highlightColor ; } public set highlightColor ( value ) { if ( this . _highlightColor === value ) { return ; } this . _highlightColor = value ; this . _markAsDirty ( ) ; } see https @ serialize ( ) public get scaleX ( ) : number { return this . _scaleX ; } public set scaleX ( value ) { if ( this . _scaleX === value ) { return ; } this . _scaleX = value ; this . _markAsDirty ( ) ; this . _markMatrixAsDirty ( ) ; } see https @ serialize ( ) public get scaleY ( ) : number { return this . _scaleY ; } public set scaleY ( value ) { if ( this . _scaleY === value ) { return ; } this . _scaleY = value ; this . _markAsDirty ( ) ; this . _markMatrixAsDirty ( ) ; } see https @ serialize ( ) public get rotation ( ) : number { return this . _rotation ; } public set rotation ( value ) { if ( this . _rotation === value ) { return ; } this . _rotation = value ; this . _markAsDirty ( ) ; this . _markMatrixAsDirty ( ) ; } see https @ serialize ( ) public get transformCenterY ( ) : number { return this . _transformCenterY ; } public set transformCenterY ( value ) { if ( this . _transformCenterY === value ) { return ; } this . _transformCenterY = value ; this . _markAsDirty ( ) ; this . _markMatrixAsDirty ( ) ; } see https @ serialize ( ) public get transformCenterX ( ) : number { return this . _transformCenterX ; } public set transformCenterX ( value ) { if ( this . _transformCenterX === value ) { return ; } this . _transformCenterX = value ; this . _markAsDirty ( ) ; this . _markMatrixAsDirty ( ) ; } see https @ serialize ( ) public get horizontalAlignment ( ) : number { return this . _horizontalAlignment ; } public set horizontalAlignment ( value ) { if ( this . _horizontalAlignment === value ) { return ; } this . _horizontalAlignment = value ; this . _markAsDirty ( ) ; } see https @ serialize ( ) public get verticalAlignment ( ) : number { return this . _verticalAlignment ; } public set verticalAlignment ( value ) { if ( this . _verticalAlignment === value ) { return ; } this . _verticalAlignment = value ; this . _markAsDirty ( ) ; } /**
     * Gets or sets a fixed ratio for this control.
     * When different from 0, the ratio is used to compute the "second" dimension.
     * The first dimension used in the computation is the last one set (by setting width / widthInPixels or height / heightInPixels), and the
     * second dimension is computed as first dimension * fixedRatio
     */ @ serialize ( ) public fixedRatio = 0 ; private _fixedRatioMasterIsWidth = true ; see https @ serialize ( ) public get width ( ) : string | number { return this . _width . toString ( this . _host ) ; } public set width ( value ) { this . _fixedRatioMasterIsWidth = true ; if ( this . _width . toString ( this . _host ) === value ) { return ; } if ( this . _width . fromString ( value ) ) { this . _markAsDirty ( ) ; } } see https public get widthInPixels ( ) : number { return this . _width . getValueInPixel ( this . _host , this . _cachedParentMeasure . width ) ; } public set widthInPixels ( value ) { if ( isNaN ( value ) ) { return ; } this . _fixedRatioMasterIsWidth = true ; this . width = value + "px" ; } see https @ serialize ( ) public get height ( ) : string | number { return this . _height . toString ( this . _host ) ; } public set height ( value ) { this . _fixedRatioMasterIsWidth = false ; if ( this . _height . toString ( this . _host ) === value ) { return ; } if ( this . _height . fromString ( value ) ) { this . _markAsDirty ( ) ; } } see https public get heightInPixels ( ) : number { return this . _height . getValueInPixel ( this . _host , this . _cachedParentMeasure . height ) ; } public set heightInPixels ( value ) { if ( isNaN ( value ) ) { return ; } this . _fixedRatioMasterIsWidth = false ; this . height = value + "px" ; } /** Gets or set font family */ public get fontFamily ( ) : string { return this . _fontFamily ; } public set fontFamily ( value ) { if ( this . _fontFamily === value ) { return ; } this . _fontFamily = value ; this . _resetFontCache ( ) ; } /** Gets or sets font style */ public get fontStyle ( ) : string { return this . _fontStyle ; } public set fontStyle ( value ) { if ( this . _fontStyle === value ) { return ; } this . _fontStyle = value ; this . _resetFontCache ( ) ; } /** Gets or sets font weight */ public get fontWeight ( ) : string { return this . _fontWeight ; } public set fontWeight ( value ) { if ( this . _fontWeight === value ) { return ; } this . _fontWeight = value ; this . _resetFontCache ( ) ; } see https @ serialize ( ) public get style ( ) : Nullable < Style > { return this . _style ; } public set style ( value ) { if ( this . _style ) { this . _style . onChangedObservable . remove ( this . _styleObserver ) ; this . _styleObserver = null ; } this . _style = value ; if ( this . _style ) { this . _styleObserver = this . _style . onChangedObservable . add ( ( ) => { this . _markAsDirty ( ) ; this . _resetFontCache ( ) ; } ) ; } this . _markAsDirty ( ) ; this . _resetFontCache ( ) ; } hidden public get _isFontSizeInPercentage ( ) : boolean { return this . _fontSize . isPercentage ; } /** Gets or sets font size in pixels */ public get fontSizeInPixels ( ) : number { let fontSizeToUse = this . _style ? this . _style . _fontSize : this . _fontSize ; if ( fontSizeToUse . isPixel ) { return fontSizeToUse . getValue ( this . _host ) ; } return fontSizeToUse . getValueInPixel ( this . _host , this . _tempParentMeasure . height || this . _cachedParentMeasure . height ) ; } public set fontSizeInPixels ( value ) { if ( isNaN ( value ) ) { return ; } this . fontSize = value + "px" ; } /** Gets or sets font size */ public get fontSize ( ) : string | number { return this . _fontSize . toString ( this . _host ) ; } public set fontSize ( value ) { if ( this . _fontSize . toString ( this . _host ) === value ) { return ; } if ( this . _fontSize . fromString ( value ) ) { this . _markAsDirty ( ) ; this . _resetFontCache ( ) ; } } /** Gets or sets foreground color */ @ serialize ( ) public get color ( ) : string { return this . _color ; } public set color ( value ) { if ( this . _color === value ) { return ; } this . _color = value ; this . _markAsDirty ( ) ; } /** Gets or sets z index which is used to reorder controls on the z axis */ @ serialize ( ) public get zIndex ( ) : number { return this . _zIndex ; } public set zIndex ( value ) { if ( this . zIndex === value ) { return ; } this . _zIndex = value ; if ( this . parent ) { this . parent . _reOrderControl ( this ) ; } } /** Gets or sets a boolean indicating if the control can be rendered */ @ serialize ( ) public get notRenderable ( ) : boolean { return this . _doNotRender ; } public set notRenderable ( value ) { if ( this . _doNotRender === value ) { return ; } this . _doNotRender = value ; this . _markAsDirty ( ) ; } /** Gets or sets a boolean indicating if the control is visible */ @ serialize ( ) public get isVisible ( ) : boolean { return this . _isVisible ; } public set isVisible ( value ) { if ( this . _isVisible === value ) { return ; } this . _isVisible = value ; this . _markAsDirty ( true ) ; } /** Gets a boolean indicating that the control needs to update its rendering */ public get isDirty ( ) : boolean { return this . _isDirty ; } /**
     * Gets the current linked mesh (or null if none)
     */ public get linkedMesh ( ) : Nullable < TransformNode > { return this . _linkedMesh ; } /**
     * Gets or sets a value indicating the padding should work like in CSS.
     * Basically, it will add the padding amount on each side of the parent control for its children.
     */ @ serialize ( ) public get descendantsOnlyPadding ( ) : boolean { return this . _descendantsOnlyPadding ; } public set descendantsOnlyPadding ( value ) { if ( this . _descendantsOnlyPadding === value ) { return ; } this . _descendantsOnlyPadding = value ; this . _markAsDirty ( ) ; } see https @ serialize ( ) public get paddingLeft ( ) : string | number { return this . _paddingLeft . toString ( this . _host ) ; } public set paddingLeft ( value ) { if ( this . _paddingLeft . fromString ( value ) ) { this . _markAsDirty ( ) ; } } see https public get paddingLeftInPixels ( ) : number { return this . _paddingLeft . getValueInPixel ( this . _host , this . _cachedParentMeasure . width ) ; } public set paddingLeftInPixels ( value ) { if ( isNaN ( value ) ) { return ; } this . paddingLeft = value + "px" ; } hidden public get _paddingLeftInPixels ( ) : number { if ( this . _descendantsOnlyPadding ) { return 0 ; } return this . paddingLeftInPixels ; } see https @ serialize ( ) public get paddingRight ( ) : string | number { return this . _paddingRight . toString ( this . _host ) ; } public set paddingRight ( value ) { if ( this . _paddingRight . fromString ( value ) ) { this . _markAsDirty ( ) ; } } see https public get paddingRightInPixels ( ) : number { return this . _paddingRight . getValueInPixel ( this . _host , this . _cachedParentMeasure . width ) ; } public set paddingRightInPixels ( value ) { if ( isNaN ( value ) ) { return ; } this . paddingRight = value + "px" ; } hidden public get _paddingRightInPixels ( ) : number { if ( this . _descendantsOnlyPadding ) { return 0 ; } return this . paddingRightInPixels ; } see https @ serialize ( ) public get paddingTop ( ) : string | number { return this . _paddingTop . toString ( this . _host ) ; } public set paddingTop ( value ) { if ( this . _paddingTop . fromString ( value ) ) { this . _markAsDirty ( ) ; } } see https public get paddingTopInPixels ( ) : number { return this . _paddingTop . getValueInPixel ( this . _host , this . _cachedParentMeasure . height ) ; } public set paddingTopInPixels ( value ) { if ( isNaN ( value ) ) { return ; } this . paddingTop = value + "px" ; } hidden public get _paddingTopInPixels ( ) : number { if ( this . _descendantsOnlyPadding ) { return 0 ; } return this . paddingTopInPixels ; } see https @ serialize ( ) public get paddingBottom ( ) : string | number { return this . _paddingBottom . toString ( this . _host ) ; } public set paddingBottom ( value ) { if ( this . _paddingBottom . fromString ( value ) ) { this . _markAsDirty ( ) ; } } see https public get paddingBottomInPixels ( ) : number { return this . _paddingBottom . getValueInPixel ( this . _host , this . _cachedParentMeasure . height ) ; } public set paddingBottomInPixels ( value ) { if ( isNaN ( value ) ) { return ; } this . paddingBottom = value + "px" ; } hidden public get _paddingBottomInPixels ( ) : number { if ( this . _descendantsOnlyPadding ) { return 0 ; } return this . paddingBottomInPixels ; } see https @ serialize ( ) public get left ( ) : string | number { return this . _left . toString ( this . _host ) ; } public set left ( value ) { if ( this . _left . fromString ( value ) ) { this . _markAsDirty ( ) ; } } see https public get leftInPixels ( ) : number { return this . _left . getValueInPixel ( this . _host , this . _cachedParentMeasure . width ) ; } public set leftInPixels ( value ) { if ( isNaN ( value ) ) { return ; } this . left = value + "px" ; } see https @ serialize ( ) public get top ( ) : string | number { return this . _top . toString ( this . _host ) ; } public set top ( value ) { if ( this . _top . fromString ( value ) ) { this . _markAsDirty ( ) ; } } see https public get topInPixels ( ) : number { return this . _top . getValueInPixel ( this . _host , this . _cachedParentMeasure . height ) ; } public set topInPixels ( value ) { if ( isNaN ( value ) ) { return ; } this . top = value + "px" ; } see https @ serialize ( ) public get linkOffsetX ( ) : string | number { return this . _linkOffsetX . toString ( this . _host ) ; } public set linkOffsetX ( value ) { if ( this . _linkOffsetX . fromString ( value ) ) { this . _markAsDirty ( ) ; } } see https public get linkOffsetXInPixels ( ) : number { return this . _linkOffsetX . getValueInPixel ( this . _host , this . _cachedParentMeasure . width ) ; } public set linkOffsetXInPixels ( value ) { if ( isNaN ( value ) ) { return ; } this . linkOffsetX = value + "px" ; } see https @ serialize ( ) public get linkOffsetY ( ) : string | number { return this . _linkOffsetY . toString ( this . _host ) ; } public set linkOffsetY ( value ) { if ( this . _linkOffsetY . fromString ( value ) ) { this . _markAsDirty ( ) ; } } see https public get linkOffsetYInPixels ( ) : number { return this . _linkOffsetY . getValueInPixel ( this . _host , this . _cachedParentMeasure . height ) ; } public set linkOffsetYInPixels ( value ) { if ( isNaN ( value ) ) { return ; } this . linkOffsetY = value + "px" ; } /** Gets the center coordinate on X axis */ public get centerX ( ) : number { return this . _currentMeasure . left + this . _currentMeasure . width / 2 ; } /** Gets the center coordinate on Y axis */ public get centerY ( ) : number { return this . _currentMeasure . top + this . _currentMeasure . height / 2 ; } /** Gets or sets if control is Enabled */ @ serialize ( ) public get isEnabled ( ) : boolean { return this . _isEnabled ; } public set isEnabled ( value ) { if ( this . _isEnabled === value ) { return ; } this . _isEnabled = value ; this . _markAsDirty ( ) ; } /** Gets or sets background color of control if it's disabled */ @ serialize ( ) public get disabledColor ( ) : string { return this . _disabledColor ; } public set disabledColor ( value ) { if ( this . _disabledColor === value ) { return ; } this . _disabledColor = value ; this . _markAsDirty ( ) ; } /** Gets or sets front color of control if it's disabled */ @ serialize ( ) public get disabledColorItem ( ) : string { return this . _disabledColorItem ; } public set disabledColorItem ( value ) { if ( this . _disabledColorItem === value ) { return ; } this . _disabledColorItem = value ; this . _markAsDirty ( ) ; } see https @ serialize ( ) public overlapGroup ? : number ; /**
     * Gets/sets the deoverlap movement multiplier
     */ @ serialize ( ) public overlapDeltaMultiplier ? : number ; param name constructor ( /** defines the name of the control */ public name ? ) { } hidden protected _getTypeName ( ) { return "Control" ; } param className returns public getAscendantOfClass ( className ) { if ( ! this . parent ) { return null ; } if ( this . parent . getClassName ( ) === className ) { return this . parent ; } return this . parent . getAscendantOfClass ( className ) ; } param force public markAsDirty ( force ) { this . _markAsDirty ( force ) ; } /**
     * Mark the element and its children as dirty
     */ public markAllAsDirty ( ) { this . _markAllAsDirty ( ) ; } hidden public _resetFontCache ( ) { this . _fontSet = true ; this . _markAsDirty ( ) ; } param container returns public isAscendant ( container ) { if ( ! this . parent ) { return false ; } if ( this . parent === container ) { return true ; } return this . parent . isAscendant ( container ) ; } param globalCoordinates returns public getLocalCoordinates ( globalCoordinates ) { var result = Vector2 . Zero ( ) ; this . getLocalCoordinatesToRef ( globalCoordinates , result ) ; return result ; } param globalCoordinates param result returns public getLocalCoordinatesToRef ( globalCoordinates , result ) { result . x = globalCoordinates . x - this . _currentMeasure . left ; result . y = globalCoordinates . y - this . _currentMeasure . top ; return this ; } param globalCoordinates returns public getParentLocalCoordinates ( globalCoordinates ) { var result = Vector2 . Zero ( ) ; result . x = globalCoordinates . x - this . _cachedParentMeasure . left ; result . y = globalCoordinates . y - this . _cachedParentMeasure . top ; return result ; } param position param scene public moveToVector3 ( position , scene ) { if ( ! this . _host || this . parent !== this . _host . _rootContainer ) { Tools . Error ( "Cannot move a control to a vector3 if the control is not at root level" ) ; return ; } this . horizontalAlignment = Control . HORIZONTAL_ALIGNMENT_LEFT ; this . verticalAlignment = Control . VERTICAL_ALIGNMENT_TOP ; var globalViewport = this . _host . _getGlobalViewport ( ) ; var projectedPosition = Vector3 . Project ( position , Matrix . Identity ( ) , scene . getTransformMatrix ( ) , globalViewport ) ; this . _moveToProjectedPosition ( projectedPosition ) ; if ( projectedPosition . z < 0 || projectedPosition . z > 1 ) { this . notRenderable = true ; return ; } this . notRenderable = false ; } param results param directDescendantsOnly param predicate public getDescendantsToRef ( results , directDescendantsOnly = false , predicate ? ) { } param directDescendantsOnly param predicate return public getDescendants ( directDescendantsOnly ? , predicate ? ) { var results = new Array < Control > ( ) ; this . getDescendantsToRef ( results , directDescendantsOnly , predicate ) ; return results ; } param mesh see https public linkWithMesh ( mesh ) { if ( ! this . _host || ( this . parent && this . parent !== this . _host . _rootContainer ) ) { if ( mesh ) { Tools . Error ( "Cannot link a control to a mesh if the control is not at root level" ) ; } return ; } var index = this . _host . _linkedControls . indexOf ( this ) ; if ( index !== - 1 ) { this . _linkedMesh = mesh ; if ( ! mesh ) { this . _host . _linkedControls . splice ( index , 1 ) ; } return ; } else if ( ! mesh ) { return ; } this . horizontalAlignment = Control . HORIZONTAL_ALIGNMENT_LEFT ; this . verticalAlignment = Control . VERTICAL_ALIGNMENT_TOP ; this . _linkedMesh = mesh ; this . _host . _linkedControls . push ( this ) ; } param { string | number } paddingTop param { string | number } paddingRight param { string | number } paddingBottom param { string | number } paddingLeft see https public setPadding ( paddingTop , paddingRight ? , paddingBottom ? , paddingLeft ? ) { const top = paddingTop ; const right = paddingRight ?? top ; const bottom = paddingBottom ?? top ; const left = paddingLeft ?? right ; this . paddingTop = top ; this . paddingRight = right ; this . paddingBottom = bottom ; this . paddingLeft = left ; } param { number } paddingTop param { number } paddingRight param { number } paddingBottom param { number } paddingLeft see https public setPaddingInPixels ( paddingTop , paddingRight ? , paddingBottom ? , paddingLeft ? ) { const top = paddingTop ; const right = paddingRight ?? top ; const bottom = paddingBottom ?? top ; const left = paddingLeft ?? right ; this . paddingTopInPixels = top ; this . paddingRightInPixels = right ; this . paddingBottomInPixels = bottom ; this . paddingLeftInPixels = left ; } hidden public _moveToProjectedPosition ( projectedPosition ) { let oldLeft = this . _left . getValue ( this . _host ) ; let oldTop = this . _top . getValue ( this . _host ) ; if ( this . _currentMeasure . width === 0 && this . _currentMeasure . height === 0 ) { let parentMeasure = this . parent ?. _currentMeasure ; if ( parentMeasure ) { this . _processMeasures ( parentMeasure , this . _host . getContext ( ) ) ; } } var newLeft = projectedPosition . x + this . _linkOffsetX . getValue ( this . _host ) - this . _currentMeasure . width / 2 ; var newTop = projectedPosition . y + this . _linkOffsetY . getValue ( this . _host ) - this . _currentMeasure . height / 2 ; if ( this . _left . ignoreAdaptiveScaling && this . _top . ignoreAdaptiveScaling ) { if ( Math . abs ( newLeft - oldLeft ) < 0.5 ) { newLeft = oldLeft ; } if ( Math . abs ( newTop - oldTop ) < 0.5 ) { newTop = oldTop ; } } this . left = newLeft + "px" ; this . top = newTop + "px" ; this . _left . ignoreAdaptiveScaling = true ; this . _top . ignoreAdaptiveScaling = true ; this . _markAsDirty ( ) ; } hidden public _offsetLeft ( offset ) { this . _isDirty = true ; this . _currentMeasure . left += offset ; } hidden public _offsetTop ( offset ) { this . _isDirty = true ; this . _currentMeasure . top += offset ; } hidden public _markMatrixAsDirty ( ) { this . _isMatrixDirty = true ; this . _flagDescendantsAsMatrixDirty ( ) ; } hidden public _flagDescendantsAsMatrixDirty ( ) { } hidden public _intersectsRect ( rect ) { this . _currentMeasure . transformToRef ( this . _transformMatrix , this . _tmpMeasureA ) ; if ( this . _tmpMeasureA . left >= rect . left + rect . width ) { return false ; } if ( this . _tmpMeasureA . top >= rect . top + rect . height ) { return false ; } if ( this . _tmpMeasureA . left + this . _tmpMeasureA . width <= rect . left ) { return false ; } if ( this . _tmpMeasureA . top + this . _tmpMeasureA . height <= rect . top ) { return false ; } return true ; } hidden protected _computeAdditionnalOffsetX ( ) { return 0 ; } hidden protected _computeAdditionnalOffsetY ( ) { return 0 ; } hidden protected invalidateRect ( ) { this . _transform ( ) ; if ( this . host && this . host . useInvalidateRectOptimization ) { this . _currentMeasure . transformToRef ( this . _transformMatrix , this . _tmpMeasureA ) ; Measure . CombineToRef ( this . _tmpMeasureA , this . _prevCurrentMeasureTransformedIntoGlobalSpace , this . _tmpMeasureA ) ; var shadowOffsetX = this . shadowOffsetX ; var shadowOffsetY = this . shadowOffsetY ; var shadowBlur = Math . max ( this . _previousShadowBlur , this . shadowBlur ) ; var leftShadowOffset = Math . min ( Math . min ( shadowOffsetX , 0 ) - shadowBlur * 2 , 0 ) ; var rightShadowOffset = Math . max ( Math . max ( shadowOffsetX , 0 ) + shadowBlur * 2 , 0 ) ; var topShadowOffset = Math . min ( Math . min ( shadowOffsetY , 0 ) - shadowBlur * 2 , 0 ) ; var bottomShadowOffset = Math . max ( Math . max ( shadowOffsetY , 0 ) + shadowBlur * 2 , 0 ) ; const offsetX = this . _computeAdditionnalOffsetX ( ) ; const offsetY = this . _computeAdditionnalOffsetY ( ) ; this . host . invalidateRect ( Math . floor ( this . _tmpMeasureA . left + leftShadowOffset - offsetX ) , Math . floor ( this . _tmpMeasureA . top + topShadowOffset - offsetY ) , Math . ceil ( this . _tmpMeasureA . left + this . _tmpMeasureA . width + rightShadowOffset + offsetX ) , Math . ceil ( this . _tmpMeasureA . top + this . _tmpMeasureA . height + bottomShadowOffset + offsetY ) ) ; } } hidden public _markAsDirty ( force = false ) { if ( ! this . _isVisible && ! force ) { return ; } this . _isDirty = true ; if ( this . _host ) { this . _host . markAsDirty ( ) ; } } hidden public _markAllAsDirty ( ) { this . _markAsDirty ( ) ; if ( this . _font ) { this . _prepareFont ( ) ; } } hidden public _link ( host ) { this . _host = host ; if ( this . _host ) { this . uniqueId = this . _host . getScene ( ) ! . getUniqueId ( ) ; } } hidden protected _transform ( context ? ) { if ( ! this . _isMatrixDirty && this . _scaleX === 1 && this . _scaleY === 1 && this . _rotation === 0 ) { return ; } var offsetX = this . _currentMeasure . width * this . _transformCenterX + this . _currentMeasure . left ; var offsetY = this . _currentMeasure . height * this . _transformCenterY + this . _currentMeasure . top ; if ( context ) { context . translate ( offsetX , offsetY ) ; context . rotate ( this . _rotation ) ; context . scale ( this . _scaleX , this . _scaleY ) ; context . translate ( - offsetX , - offsetY ) ; } if ( this . _isMatrixDirty || this . _cachedOffsetX !== offsetX || this . _cachedOffsetY !== offsetY ) { this . _cachedOffsetX = offsetX ; this . _cachedOffsetY = offsetY ; this . _isMatrixDirty = false ; this . _flagDescendantsAsMatrixDirty ( ) ; Matrix2D . ComposeToRef ( - offsetX , - offsetY , this . _rotation , this . _scaleX , this . _scaleY , this . parent ? this . parent . _transformMatrix : null , this . _transformMatrix ) ; this . _transformMatrix . invertToRef ( this . _invertTransformMatrix ) ; } } hidden public _renderHighlight ( context ) { if ( ! this . isHighlighted ) { return ; } context . save ( ) ; context . strokeStyle = this . _highlightColor ; context . lineWidth = this . _highlightLineWidth ; this . _renderHighlightSpecific ( context ) ; context . restore ( ) ; } hidden public _renderHighlightSpecific ( context ) { context . strokeRect ( this . _currentMeasure . left , this . _currentMeasure . top , this . _currentMeasure . width , this . _currentMeasure . height ) ; } hidden protected _applyStates ( context ) { if ( this . _isFontSizeInPercentage ) { this . _fontSet = true ; } if ( this . _host && this . _host . useSmallestIdeal && ! this . _font ) { this . _fontSet = true ; } if ( this . _fontSet ) { this . _prepareFont ( ) ; this . _fontSet = false ; } if ( this . _font ) { context . font = this . _font ; } if ( this . _color ) { context . fillStyle = this . _color ; } if ( Control . AllowAlphaInheritance ) { context . globalAlpha *= this . _alpha ; } else if ( this . _alphaSet ) { context . globalAlpha = this . parent && ! this . parent . renderToIntermediateTexture ? this . parent . alpha * this . _alpha : this . _alpha ; } } hidden public _layout ( parentMeasure , context ) { if ( ! this . isDirty && ( ! this . isVisible || this . notRenderable ) ) { return false ; } if ( this . _isDirty || ! this . _cachedParentMeasure . isEqualsTo ( parentMeasure ) ) { this . host . _numLayoutCalls ++ ; this . _currentMeasure . addAndTransformToRef ( this . _transformMatrix , - this . _paddingLeftInPixels | 0 , - this . _paddingTopInPixels | 0 , this . _paddingRightInPixels | 0 , this . _paddingBottomInPixels | 0 , this . _prevCurrentMeasureTransformedIntoGlobalSpace ) ; context . save ( ) ; this . _applyStates ( context ) ; let rebuildCount = 0 ; do { this . _rebuildLayout = false ; this . _processMeasures ( parentMeasure , context ) ; rebuildCount ++ ; } while ( this . _rebuildLayout && rebuildCount < 3 ) ; if ( rebuildCount >= 3 ) { Logger . Error ( `Layout cycle detected in GUI (Control name=${ this . name }, uniqueId=${ this . uniqueId })` ) ; } context . restore ( ) ; this . invalidateRect ( ) ; this . _evaluateClippingState ( parentMeasure ) ; } this . _wasDirty = this . _isDirty ; this . _isDirty = false ; return true ; } hidden protected _processMeasures ( parentMeasure , context ) { this . _tempPaddingMeasure . copyFrom ( parentMeasure ) ; if ( this . parent && this . parent . descendantsOnlyPadding ) { this . _tempPaddingMeasure . left += this . parent . paddingLeftInPixels ; this . _tempPaddingMeasure . top += this . parent . paddingTopInPixels ; this . _tempPaddingMeasure . width -= this . parent . paddingLeftInPixels + this . parent . paddingRightInPixels ; this . _tempPaddingMeasure . height -= this . parent . paddingTopInPixels + this . parent . paddingBottomInPixels ; } this . _currentMeasure . copyFrom ( this . _tempPaddingMeasure ) ; this . _preMeasure ( this . _tempPaddingMeasure , context ) ; this . _measure ( ) ; this . _computeAlignment ( this . _tempPaddingMeasure , context ) ; this . _currentMeasure . left = this . _currentMeasure . left | 0 ; this . _currentMeasure . top = this . _currentMeasure . top | 0 ; this . _currentMeasure . width = this . _currentMeasure . width | 0 ; this . _currentMeasure . height = this . _currentMeasure . height | 0 ; this . _additionalProcessing ( this . _tempPaddingMeasure , context ) ; this . _cachedParentMeasure . copyFrom ( this . _tempPaddingMeasure ) ; this . _currentMeasure . transformToRef ( this . _transformMatrix , this . _evaluatedMeasure ) ; if ( this . onDirtyObservable . hasObservers ( ) ) { this . onDirtyObservable . notifyObservers ( this ) ; } } protected _evaluateClippingState ( parentMeasure ) { this . _currentMeasure . transformToRef ( this . _transformMatrix , this . _evaluatedMeasure ) ; if ( this . parent && this . parent . clipChildren ) { parentMeasure . transformToRef ( this . parent . _transformMatrix , this . _evaluatedParentMeasure ) ; if ( this . _evaluatedMeasure . left > this . _evaluatedParentMeasure . left + this . _evaluatedParentMeasure . width ) { this . _isClipped = true ; return ; } if ( this . _evaluatedMeasure . left + this . _evaluatedMeasure . width < this . _evaluatedParentMeasure . left ) { this . _isClipped = true ; return ; } if ( this . _evaluatedMeasure . top > this . _evaluatedParentMeasure . top + this . _evaluatedParentMeasure . height ) { this . _isClipped = true ; return ; } if ( this . _evaluatedMeasure . top + this . _evaluatedMeasure . height < this . _evaluatedParentMeasure . top ) { this . _isClipped = true ; return ; } } this . _isClipped = false ; } hidden public _measure ( ) { if ( this . _width . isPixel ) { this . _currentMeasure . width = this . _width . getValue ( this . _host ) ; } else { this . _currentMeasure . width *= this . _width . getValue ( this . _host ) ; } if ( this . _height . isPixel ) { this . _currentMeasure . height = this . _height . getValue ( this . _host ) ; } else { this . _currentMeasure . height *= this . _height . getValue ( this . _host ) ; } if ( this . fixedRatio !== 0 ) { if ( this . _fixedRatioMasterIsWidth ) { this . _currentMeasure . height = this . _currentMeasure . width * this . fixedRatio ; } else { this . _currentMeasure . width = this . _currentMeasure . height * this . fixedRatio ; } } } hidden protected _computeAlignment ( parentMeasure , context ) { var width = this . _currentMeasure . width ; var height = this . _currentMeasure . height ; var parentWidth = parentMeasure . width ; var parentHeight = parentMeasure . height ; var x = 0 ; var y = 0 ; switch ( this . horizontalAlignment ) { case Control . HORIZONTAL_ALIGNMENT_LEFT : x = 0 ; break ; case Control . HORIZONTAL_ALIGNMENT_RIGHT : x = parentWidth - width ; break ; case Control . HORIZONTAL_ALIGNMENT_CENTER : x = ( parentWidth - width ) / 2 ; break ; } switch ( this . verticalAlignment ) { case Control . VERTICAL_ALIGNMENT_TOP : y = 0 ; break ; case Control . VERTICAL_ALIGNMENT_BOTTOM : y = parentHeight - height ; break ; case Control . VERTICAL_ALIGNMENT_CENTER : y = ( parentHeight - height ) / 2 ; break ; } if ( ! this . descendantsOnlyPadding ) { if ( this . _paddingLeft . isPixel ) { this . _currentMeasure . left += this . _paddingLeft . getValue ( this . _host ) ; this . _currentMeasure . width -= this . _paddingLeft . getValue ( this . _host ) ; } else { this . _currentMeasure . left += parentWidth * this . _paddingLeft . getValue ( this . _host ) ; this . _currentMeasure . width -= parentWidth * this . _paddingLeft . getValue ( this . _host ) ; } if ( this . _paddingRight . isPixel ) { this . _currentMeasure . width -= this . _paddingRight . getValue ( this . _host ) ; } else { this . _currentMeasure . width -= parentWidth * this . _paddingRight . getValue ( this . _host ) ; } if ( this . _paddingTop . isPixel ) { this . _currentMeasure . top += this . _paddingTop . getValue ( this . _host ) ; this . _currentMeasure . height -= this . _paddingTop . getValue ( this . _host ) ; } else { this . _currentMeasure . top += parentHeight * this . _paddingTop . getValue ( this . _host ) ; this . _currentMeasure . height -= parentHeight * this . _paddingTop . getValue ( this . _host ) ; } if ( this . _paddingBottom . isPixel ) { this . _currentMeasure . height -= this . _paddingBottom . getValue ( this . _host ) ; } else { this . _currentMeasure . height -= parentHeight * this . _paddingBottom . getValue ( this . _host ) ; } } if ( this . _left . isPixel ) { this . _currentMeasure . left += this . _left . getValue ( this . _host ) ; } else { this . _currentMeasure . left += parentWidth * this . _left . getValue ( this . _host ) ; } if ( this . _top . isPixel ) { this . _currentMeasure . top += this . _top . getValue ( this . _host ) ; } else { this . _currentMeasure . top += parentHeight * this . _top . getValue ( this . _host ) ; } this . _currentMeasure . left += x ; this . _currentMeasure . top += y ; } hidden protected _preMeasure ( parentMeasure , context ) { } hidden protected _additionalProcessing ( parentMeasure , context ) { } hidden protected _clipForChildren ( context ) { } private static _ClipMeasure = new Measure ( 0 , 0 , 0 , 0 ) ; private _tmpMeasureA = new Measure ( 0 , 0 , 0 , 0 ) ; private _clip ( context , invalidatedRectangle ? ) { context . beginPath ( ) ; Control . _ClipMeasure . copyFrom ( this . _currentMeasure ) ; if ( invalidatedRectangle ) { invalidatedRectangle . transformToRef ( this . _invertTransformMatrix , this . _tmpMeasureA ) ; var intersection = new Measure ( 0 , 0 , 0 , 0 ) ; intersection . left = Math . max ( this . _tmpMeasureA . left , this . _currentMeasure . left ) ; intersection . top = Math . max ( this . _tmpMeasureA . top , this . _currentMeasure . top ) ; intersection . width = Math . min ( this . _tmpMeasureA . left + this . _tmpMeasureA . width , this . _currentMeasure . left + this . _currentMeasure . width ) - intersection . left ; intersection . height = Math . min ( this . _tmpMeasureA . top + this . _tmpMeasureA . height , this . _currentMeasure . top + this . _currentMeasure . height ) - intersection . top ; Control . _ClipMeasure . copyFrom ( intersection ) ; } if ( this . shadowBlur || this . shadowOffsetX || this . shadowOffsetY ) { var shadowOffsetX = this . shadowOffsetX ; var shadowOffsetY = this . shadowOffsetY ; var shadowBlur = this . shadowBlur ; var leftShadowOffset = Math . min ( Math . min ( shadowOffsetX , 0 ) - shadowBlur * 2 , 0 ) ; var rightShadowOffset = Math . max ( Math . max ( shadowOffsetX , 0 ) + shadowBlur * 2 , 0 ) ; var topShadowOffset = Math . min ( Math . min ( shadowOffsetY , 0 ) - shadowBlur * 2 , 0 ) ; var bottomShadowOffset = Math . max ( Math . max ( shadowOffsetY , 0 ) + shadowBlur * 2 , 0 ) ; context . rect ( Control . _ClipMeasure . left + leftShadowOffset , Control . _ClipMeasure . top + topShadowOffset , Control . _ClipMeasure . width + rightShadowOffset - leftShadowOffset , Control . _ClipMeasure . height + bottomShadowOffset - topShadowOffset ) ; } else { context . rect ( Control . _ClipMeasure . left , Control . _ClipMeasure . top , Control . _ClipMeasure . width , Control . _ClipMeasure . height ) ; } context . clip ( ) ; } hidden public _render ( context , invalidatedRectangle ? ) { if ( ! this . isVisible || this . notRenderable || this . _isClipped ) { this . _isDirty = false ; return false ; } this . host . _numRenderCalls ++ ; context . save ( ) ; this . _applyStates ( context ) ; this . _transform ( context ) ; if ( this . clipContent ) { this . _clip ( context , invalidatedRectangle ) ; } if ( this . onBeforeDrawObservable . hasObservers ( ) ) { this . onBeforeDrawObservable . notifyObservers ( this ) ; } if ( this . useBitmapCache && ! this . _wasDirty && this . _cacheData ) { context . putImageData ( this . _cacheData , this . _currentMeasure . left , this . _currentMeasure . top ) ; } else { this . _draw ( context , invalidatedRectangle ) ; } if ( this . useBitmapCache && this . _wasDirty ) { this . _cacheData = context . getImageData ( this . _currentMeasure . left , this . _currentMeasure . top , this . _currentMeasure . width , this . _currentMeasure . height ) ; } this . _renderHighlight ( context ) ; if ( this . onAfterDrawObservable . hasObservers ( ) ) { this . onAfterDrawObservable . notifyObservers ( this ) ; } context . restore ( ) ; return true ; } hidden public _draw ( context , invalidatedRectangle ? ) { } param x param y returns public contains ( x , y ) { this . _invertTransformMatrix . transformCoordinates ( x , y , this . _transformedPosition ) ; x = this . _transformedPosition . x ; y = this . _transformedPosition . y ; if ( x < this . _currentMeasure . left ) { return false ; } if ( x > this . _currentMeasure . left + this . _currentMeasure . width ) { return false ; } if ( y < this . _currentMeasure . top ) { return false ; } if ( y > this . _currentMeasure . top + this . _currentMeasure . height ) { return false ; } if ( this . isPointerBlocker ) { this . _host . _shouldBlockPointer = true ; } return true ; } hidden public _processPicking ( x , y , pi , type , pointerId , buttonIndex , deltaX ? , deltaY ? ) { if ( ! this . _isEnabled ) { return false ; } if ( ! this . isHitTestVisible || ! this . isVisible || this . _doNotRender ) { return false ; } if ( ! this . contains ( x , y ) ) { return false ; } this . _processObservables ( type , x , y , pi , pointerId , buttonIndex , deltaX , deltaY ) ; return true ; } hidden public _onPointerMove ( target , coordinates , pointerId , pi ) { var canNotify = this . onPointerMoveObservable . notifyObservers ( coordinates , - 1 , target , this , pi ) ; if ( canNotify && this . parent != null ) { this . parent . _onPointerMove ( target , coordinates , pointerId , pi ) ; } } hidden public _onPointerEnter ( target , pi ) { if ( ! this . _isEnabled ) { return false ; } if ( this . _enterCount > 0 ) { return false ; } if ( this . _enterCount === - 1 ) { this . _enterCount = 0 ; } this . _enterCount ++ ; var canNotify = this . onPointerEnterObservable . notifyObservers ( this , - 1 , target , this , pi ) ; if ( canNotify && this . parent != null ) { this . parent . _onPointerEnter ( target , pi ) ; } return true ; } hidden public _onPointerOut ( target , pi , force = false ) { if ( ! force && ( ! this . _isEnabled || target === this ) ) { return ; } this . _enterCount = 0 ; var canNotify = true ; if ( ! target . isAscendant ( this ) ) { canNotify = this . onPointerOutObservable . notifyObservers ( this , - 1 , target , this , pi ) ; } if ( canNotify && this . parent != null ) { this . parent . _onPointerOut ( target , pi , force ) ; } } hidden public _onPointerDown ( target , coordinates , pointerId , buttonIndex , pi ) { this . _onPointerEnter ( this , pi ) ; if ( this . _downCount !== 0 ) { return false ; } this . _downCount ++ ; this . _downPointerIds [ pointerId ] = true ; var canNotify = this . onPointerDownObservable . notifyObservers ( new Vector2WithInfo ( coordinates , buttonIndex ) , - 1 , target , this , pi ) ; if ( canNotify && this . parent != null ) { this . parent . _onPointerDown ( target , coordinates , pointerId , buttonIndex , pi ) ; } return true ; } hidden public _onPointerUp ( target , coordinates , pointerId , buttonIndex , notifyClick , pi ? ) { if ( ! this . _isEnabled ) { return ; } this . _downCount = 0 ; delete this . _downPointerIds [ pointerId ] ; var canNotifyClick = notifyClick ; if ( notifyClick && ( this . _enterCount > 0 || this . _enterCount === - 1 ) ) { canNotifyClick = this . onPointerClickObservable . notifyObservers ( new Vector2WithInfo ( coordinates , buttonIndex ) , - 1 , target , this , pi ) ; } var canNotify = this . onPointerUpObservable . notifyObservers ( new Vector2WithInfo ( coordinates , buttonIndex ) , - 1 , target , this , pi ) ; if ( canNotify && this . parent != null ) { this . parent . _onPointerUp ( target , coordinates , pointerId , buttonIndex , canNotifyClick , pi ) ; } } hidden public _forcePointerUp ( pointerId = null ) { if ( pointerId !== null ) { this . _onPointerUp ( this , Vector2 . Zero ( ) , pointerId , 0 , true ) ; } else { for ( var key in this . _downPointerIds ) { this . _onPointerUp ( this , Vector2 . Zero ( ) , + key as number , 0 , true ) ; } } } hidden public _onWheelScroll ( deltaX ? , deltaY ? ) { if ( ! this . _isEnabled ) { return ; } var canNotify = this . onWheelObservable . notifyObservers ( new Vector2 ( deltaX , deltaY ) ) ; if ( canNotify && this . parent != null ) { this . parent . _onWheelScroll ( deltaX , deltaY ) ; } } hidden public _onCanvasBlur ( ) { } hidden public _processObservables ( type , x , y , pi , pointerId , buttonIndex , deltaX ? , deltaY ? ) { if ( ! this . _isEnabled ) { return false ; } this . _dummyVector2 . copyFromFloats ( x , y ) ; if ( type === PointerEventTypes . POINTERMOVE ) { this . _onPointerMove ( this , this . _dummyVector2 , pointerId , pi ) ; var previousControlOver = this . _host . _lastControlOver [ pointerId ] ; if ( previousControlOver && previousControlOver !== this ) { previousControlOver . _onPointerOut ( this , pi ) ; } if ( previousControlOver !== this ) { this . _onPointerEnter ( this , pi ) ; } this . _host . _lastControlOver [ pointerId ] = this ; return true ; } if ( type === PointerEventTypes . POINTERDOWN ) { this . _onPointerDown ( this , this . _dummyVector2 , pointerId , buttonIndex , pi ) ; this . _host . _registerLastControlDown ( this , pointerId ) ; this . _host . _lastPickedControl = this ; return true ; } if ( type === PointerEventTypes . POINTERUP ) { if ( this . _host . _lastControlDown [ pointerId ] ) { this . _host . _lastControlDown [ pointerId ] . _onPointerUp ( this , this . _dummyVector2 , pointerId , buttonIndex , true , pi ) ; } delete this . _host . _lastControlDown [ pointerId ] ; return true ; } if ( type === PointerEventTypes . POINTERWHEEL ) { if ( this . _host . _lastControlOver [ pointerId ] ) { this . _host . _lastControlOver [ pointerId ] . _onWheelScroll ( deltaX , deltaY ) ; return true ; } } return false ; } private _prepareFont ( ) { if ( ! this . _font && ! this . _fontSet ) { return ; } if ( this . _style ) { this . _font = this . _style . fontStyle + " " + this . _style . fontWeight + " " + this . fontSizeInPixels + "px " + this . _style . fontFamily ; } else { this . _font = this . _fontStyle + " " + this . _fontWeight + " " + this . fontSizeInPixels + "px " + this . _fontFamily ; } this . _fontOffset = Control . _GetFontOffset ( this . _font ) ; this . getDescendants ( ) . forEach ( ( child ) => child . _markAllAsDirty ( ) ) ; } param serializationObject public serialize ( serializationObject ) { SerializationHelper . Serialize ( this , serializationObject ) ; serializationObject . name = this . name ; serializationObject . className = this . getClassName ( ) ; if ( this . _font ) { serializationObject . fontFamily = this . _fontFamily ; serializationObject . fontSize = this . fontSize ; serializationObject . fontWeight = this . fontWeight ; serializationObject . fontStyle = this . fontStyle ; } } hidden public _parseFromContent ( serializedObject , host ) { if ( serializedObject . fontFamily ) { this . fontFamily = serializedObject . fontFamily ; } if ( serializedObject . fontSize ) { this . fontSize = serializedObject . fontSize ; } if ( serializedObject . fontWeight ) { this . fontWeight = serializedObject . fontWeight ; } if ( serializedObject . fontStyle ) { this . fontStyle = serializedObject . fontStyle ; } } /** Releases associated resources */ public dispose ( ) { this . onDirtyObservable . clear ( ) ; this . onBeforeDrawObservable . clear ( ) ; this . onAfterDrawObservable . clear ( ) ; this . onPointerDownObservable . clear ( ) ; this . onPointerEnterObservable . clear ( ) ; this . onPointerMoveObservable . clear ( ) ; this . onPointerOutObservable . clear ( ) ; this . onPointerUpObservable . clear ( ) ; this . onPointerClickObservable . clear ( ) ; this . onWheelObservable . clear ( ) ; if ( this . _styleObserver && this . _style ) { this . _style . onChangedObservable . remove ( this . _styleObserver ) ; this . _styleObserver = null ; } if ( this . parent ) { this . parent . removeControl ( this ) ; this . parent = null ; } if ( this . _host ) { var index = this . _host . _linkedControls . indexOf ( this ) ; if ( index > - 1 ) { this . linkWithMesh ( null ) ; } } this . onDisposeObservable . notifyObservers ( this ) ; this . onDisposeObservable . clear ( ) ; } private static _HORIZONTAL_ALIGNMENT_LEFT = 0 ; private static _HORIZONTAL_ALIGNMENT_RIGHT = 1 ; private static _HORIZONTAL_ALIGNMENT_CENTER = 2 ; private static _VERTICAL_ALIGNMENT_TOP = 0 ; private static _VERTICAL_ALIGNMENT_BOTTOM = 1 ; private static _VERTICAL_ALIGNMENT_CENTER = 2 ; /** HORIZONTAL_ALIGNMENT_LEFT */ public static get HORIZONTAL_ALIGNMENT_LEFT ( ) : number { return Control . _HORIZONTAL_ALIGNMENT_LEFT ; } /** HORIZONTAL_ALIGNMENT_RIGHT */ public static get HORIZONTAL_ALIGNMENT_RIGHT ( ) : number { return Control . _HORIZONTAL_ALIGNMENT_RIGHT ; } /** HORIZONTAL_ALIGNMENT_CENTER */ public static get HORIZONTAL_ALIGNMENT_CENTER ( ) : number { return Control . _HORIZONTAL_ALIGNMENT_CENTER ; } /** VERTICAL_ALIGNMENT_TOP */ public static get VERTICAL_ALIGNMENT_TOP ( ) : number { return Control . _VERTICAL_ALIGNMENT_TOP ; } /** VERTICAL_ALIGNMENT_BOTTOM */ public static get VERTICAL_ALIGNMENT_BOTTOM ( ) : number { return Control . _VERTICAL_ALIGNMENT_BOTTOM ; } /** VERTICAL_ALIGNMENT_CENTER */ public static get VERTICAL_ALIGNMENT_CENTER ( ) : number { return Control . _VERTICAL_ALIGNMENT_CENTER ; } private static _FontHeightSizes : { [ key ] : { ascent : number ; height : number ; descent : number ; } ; } = { } ; hidden public static _GetFontOffset ( font ) { if ( Control . _FontHeightSizes [ font ] ) { return Control . _FontHeightSizes [ font ] ; } const engine = Engine . LastCreatedEngine ; if ( ! engine ) { throw new Error ( "Invalid engine. Unable to create a canvas." ) ; } var result = engine . getFontOffset ( font ) ; Control . _FontHeightSizes [ font ] = result ; return result ; } param serializedObject param host returns public static Parse ( serializedObject , host ) { let controlType = Tools . Instantiate ( "BABYLON.GUI." + serializedObject . className ) ; let control = SerializationHelper . Parse ( ( ) => new controlType ( ) , serializedObject , null ) ; control . name = serializedObject . name ; control . _parseFromContent ( serializedObject , host ) ; return control ; } param control param text param size param options returns ignore hidden public static AddHeader : ( control : Control , text : string , size : string | number , options : { isHorizontal : boolean ; controlFirst : boolean ; } ) => any = ( ) => { } ; hidden protected static drawEllipse ( x , y , width , height , context ) { context . translate ( x , y ) ; context . scale ( width , height ) ; context . beginPath ( ) ; context . arc ( 0 , 0 , 1 , 0 , 2 * Math . PI ) ; context . closePath ( ) ; context . scale ( 1 / width , 1 / height ) ; context . translate ( - x , - y ) ; } } RegisterClass ( "BABYLON.GUI.Control" , Control ) ;