import * as React from "react" ; import { Vector4 } from "babylonjs/Maths/math.vector" ; import { Observable } from "babylonjs/Misc/observable" ; import { NumericInputComponent } from "./numericInputComponent" ; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" ; import { faMinus , faPlus } from "@fortawesome/free-solid-svg-icons" ; import { PropertyChangedEvent } from "./propertyChangedEvent" ; import { GlobalState } from "../globalState" ; interface IVector4LineComponentProps { label : string ; target ? : any ; propertyName ? : string ; value ? : Vector4 ; step ? : number ; onChange ? : ( newvalue : Vector4 ) => void ; onPropertyChangedObservable ? : Observable < PropertyChangedEvent > ; globalState : GlobalState ; } export class Vector4LineComponent extends React . Component < IVector4LineComponentProps , { isExpanded : boolean ; value : Vector4 ; } > { static defaultProps = { step : 0.001 , } ; private _localChange = false ; constructor ( props ) { super ( props ) ; this . state = { isExpanded : false , value : ( this . props . value || this . props . target [ this . props . propertyName ! ] ) . clone ( ) } ; } shouldComponentUpdate ( nextProps , nextState ) { const nextPropsValue = nextProps . value || nextProps . target [ nextProps . propertyName ! ] ; if ( ! nextPropsValue . equals ( nextState . value ) || this . _localChange ) { nextState . value = nextPropsValue . clone ( ) ; this . _localChange = false ; return true ; } return false ; } switchExpandState ( ) { this . _localChange = true ; this . setState ( { isExpanded : ! this . state . isExpanded } ) ; } raiseOnPropertyChanged ( previousValue ) { if ( this . props . onChange ) { this . props . onChange ( this . state . value ) ; } if ( ! this . props . onPropertyChangedObservable || ! this . props . propertyName ) { return ; } this . props . onPropertyChangedObservable . notifyObservers ( { object : this . props . target , property : this . props . propertyName , value : this . state . value , initialValue : previousValue , } ) ; } updateVector4 ( ) { const store = ( this . props . value || this . props . target [ this . props . propertyName ! ] ) . clone ( ) ; if ( this . props . value ) { this . props . value . copyFrom ( this . state . value ) ; } else { this . props . target [ this . props . propertyName ! ] = this . state . value ; } this . forceUpdate ( ) ; this . raiseOnPropertyChanged ( store ) ; } updateStateX ( value ) { this . _localChange = true ; this . state . value . x = value ; this . updateVector4 ( ) ; } updateStateY ( value ) { this . _localChange = true ; this . state . value . y = value ; this . updateVector4 ( ) ; } updateStateZ ( value ) { this . _localChange = true ; this . state . value . z = value ; this . updateVector4 ( ) ; } updateStateW ( value ) { this . _localChange = true ; this . state . value . w = value ; this . updateVector4 ( ) ; } render ( ) { const chevron = this . state . isExpanded ? < FontAwesomeIcon icon = { faMinus } /> : <FontAwesomeIcon icon={faPlus}/ > ; return ( < div className = "vector3Line" > < div className = "firstLine" > < div className = "label" title = { this . props . label } > { this . props . label } < /div> < div className = "vector" > { `X: ${ this . state . value . x . toFixed ( 2 ) }, Y: ${ this . state . value . y . toFixed ( 2 ) }, Z: ${ this . state . value . z . toFixed ( 2 ) }, W: ${ this . state . value . w . toFixed ( 2 ) }` } < /div> < div className = "expand hoverIcon" onClick = { ( ) => this . switchExpandState ( ) } title = "Expand" > { chevron } < /div> < /div> { this . state . isExpanded && ( < div className = "secondLine" > < NumericInputComponent globalState = { this . props . globalState } label = "x" step = { this . props . step } value = { this . state . value . x } onChange = { ( value ) => this . updateStateX ( value ) } /> < NumericInputComponent globalState = { this . props . globalState } label = "y" step = { this . props . step } value = { this . state . value . y } onChange = { ( value ) => this . updateStateY ( value ) } /> < NumericInputComponent globalState = { this . props . globalState } label = "z" step = { this . props . step } value = { this . state . value . z } onChange = { ( value ) => this . updateStateZ ( value ) } /> < NumericInputComponent globalState = { this . props . globalState } label = "w" step = { this . props . step } value = { this . state . value . w } onChange = { ( value ) => this . updateStateW ( value ) } /> < /div>)} < /div>); } }