floatLineComponent.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import * as React from "react";
  2. import { Observable } from "babylonjs";
  3. import { PropertyChangedEvent } from "../../propertyChangedEvent";
  4. import { LockObject } from "../tabs/propertyGrids/lockObject";
  5. interface IFloatLineComponentProps {
  6. label: string,
  7. target: any,
  8. propertyName: string,
  9. lockObject?: LockObject,
  10. onChange?: (newValue: number) => void,
  11. isInteger?: boolean,
  12. onPropertyChangedObservable?: Observable<PropertyChangedEvent>,
  13. additionalClass?: string
  14. }
  15. export class FloatLineComponent extends React.Component<IFloatLineComponentProps, { value: string }> {
  16. private _localChange = false;
  17. private _store: number;
  18. constructor(props: IFloatLineComponentProps) {
  19. super(props);
  20. let currentValue = this.props.target[this.props.propertyName];
  21. this.state = { value: currentValue ? (this.props.isInteger ? currentValue.toFixed(0) : currentValue.toFixed(3)) : "0" }
  22. this._store = currentValue;
  23. }
  24. componentWillUnmount() {
  25. this.unlock();
  26. }
  27. shouldComponentUpdate(nextProps: IFloatLineComponentProps, nextState: { value: string }) {
  28. if (this._localChange) {
  29. this._localChange = false;
  30. return true;
  31. }
  32. const newValue = nextProps.target[nextProps.propertyName];
  33. const newValueString = newValue ? this.props.isInteger ? newValue.toFixed(0) : newValue.toFixed(3) : "0";
  34. if (newValueString !== nextState.value) {
  35. nextState.value = newValueString;
  36. return true;
  37. }
  38. return false;
  39. }
  40. raiseOnPropertyChanged(newValue: number, previousValue: number) {
  41. if (this.props.onChange) {
  42. this.props.onChange(newValue);
  43. }
  44. if (!this.props.onPropertyChangedObservable) {
  45. return;
  46. }
  47. this.props.onPropertyChangedObservable.notifyObservers({
  48. object: this.props.target,
  49. property: this.props.propertyName,
  50. value: newValue,
  51. initialValue: previousValue
  52. });
  53. }
  54. updateValue(valueString: string) {
  55. if (/[^0-9\.\-]/g.test(valueString)) {
  56. return;
  57. }
  58. let valueAsNumber: number
  59. if (this.props.isInteger) {
  60. valueAsNumber = parseInt(valueString);
  61. } else {
  62. valueAsNumber = parseFloat(valueString);
  63. }
  64. this._localChange = true;
  65. this.setState({ value: valueString });
  66. if (isNaN(valueAsNumber)) {
  67. return;
  68. }
  69. this.raiseOnPropertyChanged(valueAsNumber, this._store);
  70. this.props.target[this.props.propertyName] = valueAsNumber;
  71. this._store = valueAsNumber;
  72. }
  73. lock() {
  74. if (this.props.lockObject) {
  75. this.props.lockObject.lock = true;
  76. }
  77. }
  78. unlock() {
  79. if (this.props.lockObject) {
  80. this.props.lockObject.lock = false;
  81. }
  82. }
  83. render() {
  84. return (
  85. <div className={this.props.additionalClass ? this.props.additionalClass + " floatLine" : "floatLine"}>
  86. <div className="label">
  87. {this.props.label}
  88. </div>
  89. <div className="value">
  90. <input type="number" step="0.01" className="numeric-input" value={this.state.value} onBlur={() => this.unlock()} onFocus={() => this.lock()} onChange={evt => this.updateValue(evt.target.value)} />
  91. </div>
  92. </div>
  93. );
  94. }
  95. }