David Catuhe 5 лет назад
Родитель
Сommit
3268284f5f

+ 21 - 0
nodeEditor/src/components/propertyTab/properties/color4PropertyTabComponent.tsx

@@ -0,0 +1,21 @@
+
+import * as React from "react";
+import { GlobalState } from '../../../globalState';
+import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
+import { Color4LineComponent } from '../../../sharedComponents/color4LineComponent';
+
+interface IColor4PropertyTabComponentProps {
+    globalState: GlobalState;
+    inputBlock: InputBlock;
+}
+
+export class Color4PropertyTabComponent extends React.Component<IColor4PropertyTabComponentProps> {
+
+    render() {
+        return (
+            <Color4LineComponent globalState={this.props.globalState} label="Value" target={this.props.inputBlock} propertyName="value" onChange={() => {
+                this.props.globalState.onUpdateRequiredObservable.notifyObservers();
+            }}></Color4LineComponent>
+        );
+    }
+}

+ 5 - 1
nodeEditor/src/diagram/properties/inputNodePropertyComponent.tsx

@@ -19,6 +19,7 @@ import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
 import { GenericPropertyTabComponent } from './genericNodePropertyComponent';
 import { TextInputLineComponent } from '../../sharedComponents/textInputLineComponent';
 import { CheckBoxLineComponent } from '../../sharedComponents/checkBoxLineComponent';
+import { Color4PropertyTabComponent } from '../../components/propertyTab/properties/color4PropertyTabComponent';
 
 export class InputPropertyTabComponent extends React.Component<IPropertyComponentProps> {
     constructor(props: IPropertyComponentProps) {
@@ -75,10 +76,13 @@ export class InputPropertyTabComponent extends React.Component<IPropertyComponen
                     <Vector2PropertyTabComponent globalState={globalState} inputBlock={inputBlock} />
                 );
             case NodeMaterialBlockConnectionPointTypes.Color3:
-            case NodeMaterialBlockConnectionPointTypes.Color4:
                 return (
                     <Color3PropertyTabComponent globalState={globalState} inputBlock={inputBlock} />
                 );
+            case NodeMaterialBlockConnectionPointTypes.Color4:
+                return (
+                    <Color4PropertyTabComponent globalState={globalState} inputBlock={inputBlock} />
+                );
             case NodeMaterialBlockConnectionPointTypes.Vector3:
                 return (
                     <Vector3PropertyTabComponent globalState={globalState} inputBlock={inputBlock} />

+ 174 - 0
nodeEditor/src/sharedComponents/color4LineComponent.tsx

@@ -0,0 +1,174 @@
+import * as React from "react";
+import { Observable } from "babylonjs/Misc/observable";
+import { Color3, Color4 } from "babylonjs/Maths/math";
+import { PropertyChangedEvent } from "./propertyChangedEvent";
+import { NumericInputComponent } from "./numericInputComponent";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { faMinus, faPlus, faCopy } from "@fortawesome/free-solid-svg-icons";
+import { GlobalState } from '../globalState';
+
+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: IColor4LineComponentProps) {
+        super(props);
+
+        this.state = { isExpanded: false, color: this.props.target[this.props.propertyName].clone() };
+    }
+
+    shouldComponentUpdate(nextProps: IColor4LineComponentProps, nextState: { color: Color4 }) {
+        const currentState = nextProps.target[nextProps.propertyName];
+
+        if (!currentState.equals(nextState.color) || this._localChange) {
+            nextState.color = currentState.clone();
+            this._localChange = false;
+            return true;
+        }
+        return false;
+    }
+
+    onChange(newValue: string) {
+        this._localChange = true;
+        const newColor = Color3.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] = new Color4(newColor.r, newColor.g, newColor.b, this.props.target[this.props.propertyName].a);
+
+        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: Color4) {
+        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: number) {
+        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: number) {
+        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: number) {
+        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: number) {
+        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 chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />
+        const colorAsColor3 = this.state.color.getClassName() === "Color3" ? this.state.color : new Color3(this.state.color.r, this.state.color.g, this.state.color.b);
+
+        return (
+            <div className="color3Line">
+                <div className="firstLine">
+                    <div className="label">
+                        {this.props.label}
+                    </div>
+                    <div className="color3">
+                        <input type="color" value={colorAsColor3.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
+                    </div>
+                    <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
+                        <FontAwesomeIcon icon={faCopy} />
+                    </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="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>
+        );
+    }
+}