import * as React from "react" ; import { Observable } from "babylonjs/Misc/observable" ; import { Color4 } from "babylonjs/Maths/math.color" ; import { PropertyChangedEvent } from "./propertyChangedEvent" ; import { NumericInputComponent } from "./numericInputComponent" ; import { GlobalState } from "../globalState" ; import { ColorPickerLineComponent } from "./colorPickerComponent" ; const copyIcon = require ( "./copy.svg" ) ; const plusIcon = require ( "./plus.svg" ) ; const minusIcon = require ( "./minus.svg" ) ; export interface IColor4LineComponentProps { label : string ; target : any ; propertyName : string ; onPropertyChangedObservable ? : Observable < PropertyChangedEvent > ; onChange ? : ( ) => void ; globalState : GlobalState ; } export class Color4LineComponent extends React . Component < IColor4LineComponentProps , { isExpanded : boolean ; color : Color4 ; } > { private _localChange = false ; constructor ( props ) { super ( props ) ; let value = this . props . target [ this . props . propertyName ] ; let currentColor = value . getClassName ( ) === "Color4" ? value . clone ( ) : new Color4 ( value . r , value . g , value . b , 1.0 ) ; this . state = { isExpanded : false , color : currentColor } ; } shouldComponentUpdate ( nextProps , nextState ) { const currentState = nextProps . target [ nextProps . propertyName ] ; let currentColor = currentState . getClassName ( ) === "Color4" ? currentState : new Color4 ( currentState . r , currentState . g , currentState . b , 1.0 ) ; if ( ! currentColor . equals ( nextState . color ) || this . _localChange ) { nextState . color = currentColor . clone ( ) ; this . _localChange = false ; return true ; } return false ; } onChange ( newValue ) { this . _localChange = true ; const newColor = Color4 . FromHexString ( newValue ) ; if ( this . props . onPropertyChangedObservable ) { this . props . onPropertyChangedObservable . notifyObservers ( { object : this . props . target , property : this . props . propertyName , value : newColor , initialValue : this . state . color , } ) ; } this . props . target [ this . props . propertyName ] = newColor ; this . setState ( { color : this . props . target [ this . props . propertyName ] } ) ; if ( this . props . onChange ) { this . props . onChange ( ) ; } } switchExpandState ( ) { this . _localChange = true ; this . setState ( { isExpanded : ! this . state . isExpanded } ) ; } raiseOnPropertyChanged ( previousValue ) { if ( this . props . onChange ) { this . props . onChange ( ) ; } if ( ! this . props . onPropertyChangedObservable ) { return ; } this . props . onPropertyChangedObservable . notifyObservers ( { object : this . props . target , property : this . props . propertyName , value : this . state . color , initialValue : previousValue , } ) ; } updateStateR ( value ) { this . _localChange = true ; const store = this . state . color . clone ( ) ; this . props . target [ this . props . propertyName ] . x = value ; this . state . color . r = value ; this . props . target [ this . props . propertyName ] = this . state . color ; this . setState ( { color : this . state . color } ) ; this . raiseOnPropertyChanged ( store ) ; } updateStateG ( value ) { this . _localChange = true ; const store = this . state . color . clone ( ) ; this . props . target [ this . props . propertyName ] . g = value ; this . state . color . g = value ; this . props . target [ this . props . propertyName ] = this . state . color ; this . setState ( { color : this . state . color } ) ; this . raiseOnPropertyChanged ( store ) ; } updateStateB ( value ) { this . _localChange = true ; const store = this . state . color . clone ( ) ; this . props . target [ this . props . propertyName ] . b = value ; this . state . color . b = value ; this . props . target [ this . props . propertyName ] = this . state . color ; this . setState ( { color : this . state . color } ) ; this . raiseOnPropertyChanged ( store ) ; } updateStateA ( value ) { this . _localChange = true ; const store = this . state . color . clone ( ) ; this . props . target [ this . props . propertyName ] . a = value ; this . state . color . a = value ; this . props . target [ this . props . propertyName ] = this . state . color ; this . setState ( { color : this . state . color } ) ; this . raiseOnPropertyChanged ( store ) ; } copyToClipboard ( ) { var element = document . createElement ( "div" ) ; element . textContent = this . state . color . toHexString ( ) ; document . body . appendChild ( element ) ; if ( window . getSelection ) { var range = document . createRange ( ) ; range . selectNode ( element ) ; window . getSelection ( ) ! . removeAllRanges ( ) ; window . getSelection ( ) ! . addRange ( range ) ; } document . execCommand ( "copy" ) ; element . remove ( ) ; } render ( ) { const expandedIcon = this . state . isExpanded ? minusIcon : plusIcon ; return ( < div className = "color3Line" > < div className = "firstLine" > < div className = "label" title = { this . props . label } > { this . props . label } < /div> < div className = "color3" > < ColorPickerLineComponent globalState = { this . props . globalState } value = { this . state . color } onColorChanged = { ( color ) => { this . onChange ( color ) ; } } /> < /div> < div className = "copy hoverIcon" onClick = { ( ) => this . copyToClipboard ( ) } title = "Copy to clipboard" > < img src = { copyIcon } alt = "" / > < /div> < div className = "expand hoverIcon" onClick = { ( ) => this . switchExpandState ( ) } title = "Expand" > < img src = { expandedIcon } alt = "" / > < /div> < /div> { this . state . isExpanded && ( < div className = "secondLine" > < NumericInputComponent globalState = { this . props . globalState } label = "r" value = { this . state . color . r } onChange = { ( value ) => this . updateStateR ( value ) } /> < NumericInputComponent globalState = { this . props . globalState } label = "g" value = { this . state . color . g } onChange = { ( value ) => this . updateStateG ( value ) } /> < NumericInputComponent globalState = { this . props . globalState } label = "b" value = { this . state . color . b } onChange = { ( value ) => this . updateStateB ( value ) } /> < NumericInputComponent globalState = { this . props . globalState } label = "a" value = { this . state . color . a } onChange = { ( value ) => this . updateStateA ( value ) } /> < /div>)} < /div>); } }