Explorar el Código

adding float input

Pamela Wolf hace 4 años
padre
commit
4b1e6c5d41

+ 39 - 5
inspector/src/components/actionTabs/actionTabs.scss

@@ -972,10 +972,13 @@ $line-padding-left: 2px;
                 }
 
                 .sliderLine {
-                    padding-left: 2px;
+                    padding-left: $line-padding-left;
                     height: 30px;
                     display: grid;
-                    grid-template-columns: 1fr auto;
+                    grid-template-rows: 100%;
+                    grid-template-columns: 1fr 40px;
+            
+
 
                     .label {
                         grid-column: 1;
@@ -983,12 +986,43 @@ $line-padding-left: 2px;
                         align-items: center;
                     }
 
+                    .floatLine {
+                        padding-left: $line-padding-left;
+                
+                        .label {
+                            grid-column: 1;
+                            display: flex;
+                            align-items: center;
+                        }
+                    
+                        .short {
+                            grid-column: 1; 
+                            display: flex;
+                            align-items: center;
+                            
+                            input {
+                                width: 27px;
+                            }
+                            
+                            input::-webkit-outer-spin-button,
+                            input::-webkit-inner-spin-button {
+                              -webkit-appearance: none;
+                              margin: 0;
+                            }
+                
+                            input[type=number] {
+                                -moz-appearance: textfield;
+                            }
+                        }
+                    }  
+
                     .slider {
-                        grid-column: 2;
+                        grid-column: 3;
+                        grid-row: 1;
                         margin-right: 5px;
-                        
+                        width: 90%;
                         display: flex;
-                        align-items: center;
+                        align-items: center;            
 
                         .range {
                             -webkit-appearance: none;

+ 48 - 54
inspector/src/components/actionTabs/lines/floatLineComponent.tsx

@@ -5,37 +5,45 @@ import { PropertyChangedEvent } from "../../propertyChangedEvent";
 import { LockObject } from "../tabs/propertyGrids/lockObject";
 import { SliderLineComponent } from './sliderLineComponent';
 import { Tools } from 'babylonjs/Misc/tools';
+import { GlobalState } from '../../globalState';
+
 
 interface IFloatLineComponentProps {
     label: string;
     target: any;
     propertyName: string;
-    lockObject?: LockObject;
     onChange?: (newValue: number) => void;
     isInteger?: boolean;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
     additionalClass?: string;
-    step?: string,
+    step?: string;
     digits?: number;
-    useEuler?: boolean;
-    min?: number;
-    max?: number;
+    globalState: GlobalState;
+    min?: number
+    max?: number
+    smallUI?: boolean;
+    onEnter?: (newValue:number) => void;
 }
 
 export class FloatLineComponent extends React.Component<IFloatLineComponentProps, { value: string }> {
     private _localChange = false;
     private _store: number;
+    private _regExp: RegExp;
 
     constructor(props: IFloatLineComponentProps) {
         super(props);
-
         let currentValue = this.props.target[this.props.propertyName];
-        this.state = { value: currentValue ? (this.props.isInteger ? currentValue.toFixed(0) : currentValue.toFixed(this.props.digits || 3)) : "0" };
+        this.state = { value: currentValue ? (this.props.isInteger ? currentValue.toFixed(0) : currentValue.toFixed(this.props.digits || 2)) : "0" };
         this._store = currentValue;
-    }
 
-    componentWillUnmount() {
-        this.unlock();
+        let rexp = "(.*\\.";
+        let numDigits = this.props.digits || 2;
+        while (numDigits--) {
+            rexp += ".";
+        }
+        rexp += ").+";
+
+        this._regExp = new RegExp(rexp);
     }
 
     shouldComponentUpdate(nextProps: IFloatLineComponentProps, nextState: { value: string }) {
@@ -45,7 +53,7 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
         }
 
         const newValue = nextProps.target[nextProps.propertyName];
-        const newValueString = newValue ? this.props.isInteger ? newValue.toFixed(0) : newValue.toFixed(this.props.digits || 3) : "0";
+        const newValueString = newValue ? this.props.isInteger ? newValue.toFixed(0) : newValue.toFixed(this.props.digits || 2) : "0";
 
         if (newValueString !== nextState.value) {
             nextState.value = newValueString;
@@ -71,11 +79,12 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
     }
 
     updateValue(valueString: string) {
-
         if (/[^0-9\.\-]/g.test(valueString)) {
             return;
         }
 
+        valueString = valueString.replace(this._regExp, "$1");
+
         let valueAsNumber: number;
 
         if (this.props.isInteger) {
@@ -84,27 +93,18 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
             valueAsNumber = parseFloat(valueString);
         }
 
-        if (!isNaN(valueAsNumber)) {
-            if (this.props.min !== undefined) {
-                if (valueAsNumber < this.props.min) {
-                    valueAsNumber = this.props.min;
-                    valueString = valueAsNumber.toString();
-                }            
-            }
-            if (this.props.max !== undefined) {
-                if (valueAsNumber > this.props.max) {
-                    valueAsNumber = this.props.max;
-                    valueString = valueAsNumber.toString();
-                }            
-            }
-        }
-
         this._localChange = true;
-        this.setState({ value: valueString });
+        this.setState({ value: valueString});
 
         if (isNaN(valueAsNumber)) {
             return;
         }
+        if(this.props.max != undefined && (valueAsNumber > this.props.max)) {
+            valueAsNumber = this.props.max;
+        }
+        if(this.props.min != undefined && (valueAsNumber < this.props.min)) {
+            valueAsNumber = this.props.min;
+        }
 
         this.props.target[this.props.propertyName] = valueAsNumber;
         this.raiseOnPropertyChanged(valueAsNumber, this._store);
@@ -112,45 +112,39 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
         this._store = valueAsNumber;
     }
 
-    lock() {
-        if (this.props.lockObject) {
-            this.props.lockObject.lock = true;
-        }
-    }
-
-    unlock() {
-        if (this.props.lockObject) {
-            this.props.lockObject.lock = false;
-        }
-    }
-
     render() {
-        let valueAsNumber: number;
-
-        if (this.props.isInteger) {
-            valueAsNumber = parseInt(this.state.value);
-        } else {
-            valueAsNumber = parseFloat(this.state.value);
-        }
+        let className = this.props.smallUI ? "short": "value";
 
         return (
             <div>
                 {
-                    !this.props.useEuler &&
                     <div className={this.props.additionalClass ? this.props.additionalClass + " floatLine" : "floatLine"}>
                         <div className="label">
                             {this.props.label}
                         </div>
-                        <div className="value">
-                            <input type="number" step={this.props.step || this.props.isInteger ? "1" : "0.01"} className="numeric-input" value={this.state.value} onBlur={() => this.unlock()} onFocus={() => this.lock()} onChange={evt => this.updateValue(evt.target.value)} />
+                        <div className={className}>
+                            <input type="number" step={this.props.step || "0.01"} className="numeric-input"
+                            onBlur={(evt) => {
+                                this.props.globalState.blockKeyboardEvents = false;
+                                if(this.props.onEnter) {
+                                    this.props.onEnter(this._store);
+                                }
+                            }}
+                            onKeyDown={evt => {
+                                if (evt.keyCode !== 13) {
+                                    return;
+                                }
+                                if(this.props.onEnter) {
+                                    this.props.onEnter(this._store);
+                                }
+                            }}
+                            onFocus={() => this.props.globalState.blockKeyboardEvents = true}
+                            value={this.state.value} onChange={(evt) => this.updateValue(evt.target.value)} />
                         </div>
                     </div>
                 }
-                {
-                    this.props.useEuler &&
-                    <SliderLineComponent label={this.props.label} minimum={0} maximum={360} step={0.1} directValue={Tools.ToDegrees(valueAsNumber)} onChange={value => this.updateValue(Tools.ToRadians(value).toString())} />
-                }
             </div>
         );
     }
 }
+

+ 5 - 3
inspector/src/components/actionTabs/lines/quaternionLineComponent.tsx

@@ -7,6 +7,7 @@ import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
 import { PropertyChangedEvent } from "../../propertyChangedEvent";
 import { Tools } from 'babylonjs/Misc/tools';
 import { SliderLineComponent } from './sliderLineComponent';
+import { GlobalState } from '../../globalState';
 
 interface IQuaternionLineComponentProps {
     label: string;
@@ -14,6 +15,7 @@ interface IQuaternionLineComponentProps {
     useEuler?: boolean;
     propertyName: string;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+    globalState: GlobalState
 }
 
 export class QuaternionLineComponent extends React.Component<IQuaternionLineComponentProps, { isExpanded: boolean, value: Quaternion, eulerValue: Vector3 }> {
@@ -162,9 +164,9 @@ export class QuaternionLineComponent extends React.Component<IQuaternionLineComp
                 {
                     this.state.isExpanded && this.props.useEuler &&
                     <div className="secondLine">
-                        <SliderLineComponent label="x" minimum={0} maximum={360} step={0.1} directValue={Tools.ToDegrees(euler.x)} onChange={value => this.updateStateEulerX(value)} />
-                        <SliderLineComponent label="y" minimum={0} maximum={360} step={0.1} directValue={Tools.ToDegrees(euler.y)} onChange={value => this.updateStateEulerY(value)} />
-                        <SliderLineComponent label="z" minimum={0} maximum={360} step={0.1} directValue={Tools.ToDegrees(euler.z)} onChange={value => this.updateStateEulerZ(value)} />
+                        <SliderLineComponent globalState={this.props.globalState} label="x" minimum={0} maximum={360} step={0.1} directValue={Tools.ToDegrees(euler.x)} onChange={value => this.updateStateEulerX(value)} />
+                        <SliderLineComponent globalState={this.props.globalState} label="y" minimum={0} maximum={360} step={0.1} directValue={Tools.ToDegrees(euler.y)} onChange={value => this.updateStateEulerY(value)} />
+                        <SliderLineComponent globalState={this.props.globalState} label="z" minimum={0} maximum={360} step={0.1} directValue={Tools.ToDegrees(euler.z)} onChange={value => this.updateStateEulerZ(value)} />
                     </div>
                 }
             </div>

+ 17 - 9
inspector/src/components/actionTabs/lines/sliderLineComponent.tsx

@@ -2,6 +2,8 @@ import * as React from "react";
 import { Observable } from "babylonjs/Misc/observable";
 import { PropertyChangedEvent } from "../../propertyChangedEvent";
 import { Tools } from 'babylonjs/Misc/tools';
+import { FloatLineComponent } from './floatLineComponent';
+import { GlobalState } from '../../globalState';
 
 interface ISliderLineComponentProps {
     label: string;
@@ -13,9 +15,10 @@ interface ISliderLineComponentProps {
     directValue?: number;
     useEuler?: boolean;
     onChange?: (value: number) => void;
-    onInput?: (value: number) => void;    
+    onInput?: (value: number) => void;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
     decimalCount?: number;
+    globalState: GlobalState;
 }
 
 export class SliderLineComponent extends React.Component<ISliderLineComponentProps, { value: number }> {
@@ -48,8 +51,8 @@ export class SliderLineComponent extends React.Component<ISliderLineComponentPro
             currentState = nextProps.maximum;
         }
 
-        if (currentState !== nextState.value || this._localChange || nextProps.maximum !== this.props.maximum || nextProps.minimum !== this.props.minimum) {
-            nextState.value = currentState;
+        if (currentState !== nextState.value || nextProps.minimum !== this.props.minimum || nextProps.maximum !== this.props.maximum || this._localChange) {
+            nextState.value = Math.min(Math.max(currentState, nextProps.minimum), nextProps.maximum);
             this._localChange = false;
             return true;
         }
@@ -92,10 +95,6 @@ export class SliderLineComponent extends React.Component<ISliderLineComponentPro
     }
 
     prepareDataToRead(value: number) {
-        if (value === null) {
-            value = 0;
-        }
-
         if (this.props.useEuler) {
             return Tools.ToDegrees(value);
         }
@@ -104,14 +103,23 @@ export class SliderLineComponent extends React.Component<ISliderLineComponentPro
     }
 
     render() {
-        let decimalCount = this.props.decimalCount !== undefined ? this.props.decimalCount : 2;
+
+        var input = // this.props.globalState ? 
+        <FloatLineComponent globalState={this.props.globalState} smallUI={true} label="" target={this.state} propertyName="value" min={this.prepareDataToRead(this.props.minimum)} max={this.prepareDataToRead(this.props.maximum)}
+        onEnter={ () => { 
+            this.onChange(this.state.value)
+        }
+        } > 
+        </FloatLineComponent> ;
+        //: null;
         return (
             <div className="sliderLine">
                 <div className="label">
                     {this.props.label}
                 </div>
+                {input}
                 <div className="slider">
-                    {this.state.value ? this.prepareDataToRead(this.state.value).toFixed(decimalCount) : "0"}&nbsp;<input className="range" type="range" step={this.props.step} min={this.prepareDataToRead(this.props.minimum)} max={this.prepareDataToRead(this.props.maximum)} value={this.prepareDataToRead(this.state.value)}
+                    <input className="range" type="range" step={this.props.step} min={this.prepareDataToRead(this.props.minimum)} max={this.prepareDataToRead(this.props.maximum)} value={this.prepareDataToRead(this.state.value)}
                         onInput={evt => this.onInput((evt.target as HTMLInputElement).value)}
                         onChange={evt => this.onChange(evt.target.value)} />
                 </div>

+ 2 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/customPropertyGridComponent.tsx

@@ -35,7 +35,7 @@ export class CustomPropertyGridComponent extends React.Component<ICustomProperty
                 )
             case InspectableType.Slider:
                 return (
-                    <SliderLineComponent key={inspectable.label} label={inspectable.label} target={this.props.target} propertyName={inspectable.propertyName}
+                    <SliderLineComponent globalState={this.props.globalState} key={inspectable.label} label={inspectable.label} target={this.props.target} propertyName={inspectable.propertyName}
                         step={inspectable.step !== undefined ? inspectable.step : 0.1}
                         minimum={inspectable.min !== undefined ? inspectable.min : 0} maximum={inspectable.max !== undefined ? inspectable.max : 1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 )
@@ -46,7 +46,7 @@ export class CustomPropertyGridComponent extends React.Component<ICustomProperty
                 )
             case InspectableType.Quaternion:
                 return (
-                    <QuaternionLineComponent useEuler={this.props.globalState.onlyUseEulers} key={inspectable.label} label={inspectable.label} target={this.props.target} propertyName={inspectable.propertyName}
+                    <QuaternionLineComponent globalState={this.props.globalState} useEuler={this.props.globalState.onlyUseEulers} key={inspectable.label} label={inspectable.label} target={this.props.target} propertyName={inspectable.propertyName}
                         onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 )
             case InspectableType.Color3:

+ 1 - 0
inspector/src/components/globalState.ts

@@ -73,6 +73,7 @@ export class GlobalState {
     public recorder = new ReplayRecorder();
 
     private _onlyUseEulers: Nullable<boolean> = null;
+    public blockKeyboardEvents = false;
 
     public get onlyUseEulers(): boolean {
         if (this._onlyUseEulers === null) {