hexLineComponent.tsx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import * as React from "react";
  2. import { Observable } from "babylonjs/Misc/observable";
  3. import { PropertyChangedEvent } from "../propertyChangedEvent";
  4. import { LockObject } from "../tabs/propertyGrids/lockObject";
  5. interface IHexLineComponentProps {
  6. label: string;
  7. target: any;
  8. propertyName: string;
  9. lockObject?: LockObject;
  10. onChange?: (newValue: number) => void;
  11. isInteger?: boolean;
  12. replaySourceReplacement?: string;
  13. onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
  14. additionalClass?: string;
  15. step?: string,
  16. digits?: number;
  17. useEuler?: boolean;
  18. min?: number
  19. }
  20. export class HexLineComponent extends React.Component<IHexLineComponentProps, { value: string }> {
  21. private _localChange = false;
  22. private _store: number;
  23. private _propertyChange = true;
  24. constructor(props: IHexLineComponentProps) {
  25. super(props);
  26. let currentValue = this.props.target[this.props.propertyName];
  27. this.state = { value: currentValue ? (this.props.isInteger ? currentValue.toFixed(0) : currentValue.toFixed(this.props.digits || 3)) : "0" };
  28. this._store = currentValue;
  29. }
  30. componentWillUnmount() {
  31. this.unlock();
  32. }
  33. shouldComponentUpdate(nextProps: IHexLineComponentProps, nextState: { value: string }) {
  34. if (this._localChange) {
  35. this._localChange = false;
  36. return true;
  37. }
  38. const newValue = nextProps.target[nextProps.propertyName];
  39. const newValueString = newValue ? this.props.isInteger ? newValue.toFixed(0) : newValue.toFixed(this.props.digits || 3) : "0";
  40. if (newValueString !== nextState.value) {
  41. nextState.value = newValueString;
  42. return true;
  43. }
  44. return false;
  45. }
  46. raiseOnPropertyChanged(newValue: number, previousValue: number) {
  47. if (this.props.onChange) {
  48. this.props.onChange(newValue);
  49. }
  50. if (!this.props.onPropertyChangedObservable) {
  51. return;
  52. }
  53. this.props.onPropertyChangedObservable.notifyObservers({
  54. object: this.props.replaySourceReplacement ?? this.props.target,
  55. property: this.props.propertyName,
  56. value: newValue,
  57. initialValue: previousValue
  58. });
  59. }
  60. convertToHexString(valueString: string): string
  61. {
  62. while(valueString.length < 10)
  63. {
  64. valueString += "0";
  65. }
  66. return valueString;
  67. }
  68. updateValue(valueString: string, raisePropertyChanged: boolean) {
  69. if(valueString.substr(0,2) != "0x") {
  70. if(valueString.substr(0,1) != "0") {
  71. valueString = "0x" + valueString;
  72. }
  73. else {
  74. valueString = "0x" + valueString.substr(1);
  75. }
  76. }
  77. let valueSubstr = valueString.substr(2);
  78. if (valueSubstr != "" && /^[0-9A-Fa-f]+$/g.test(valueSubstr) == false) {
  79. return;
  80. }
  81. if(valueString.length > 10) {
  82. return;
  83. }
  84. let valueStringAsHex = this.convertToHexString(valueString);
  85. let valueAsNumber: number;
  86. valueAsNumber = parseInt(valueStringAsHex);
  87. if (!isNaN(valueAsNumber) && this.props.min !== undefined) {
  88. if (valueAsNumber < this.props.min) {
  89. valueAsNumber = this.props.min;
  90. valueString = valueAsNumber.toString();
  91. }
  92. }
  93. this._localChange = true;
  94. if (isNaN(valueAsNumber)) {
  95. return;
  96. }
  97. this.setState({ value: valueString });
  98. if(raisePropertyChanged)
  99. {
  100. this._propertyChange = true;
  101. this.props.target[this.props.propertyName] = valueAsNumber;
  102. this.raiseOnPropertyChanged(valueAsNumber, this._store);
  103. }
  104. else
  105. {
  106. this._propertyChange = false;
  107. }
  108. this._store = valueAsNumber;
  109. }
  110. lock() {
  111. if (this.props.lockObject) {
  112. this.props.lockObject.lock = true;
  113. }
  114. }
  115. unlock() {
  116. if (this.props.lockObject) {
  117. this.props.lockObject.lock = false;
  118. }
  119. }
  120. render() {
  121. let valueAsHex : string;
  122. if(this._propertyChange)
  123. {
  124. let valueAsNumber = parseInt(this.state.value);
  125. valueAsHex = valueAsNumber.toString(16);
  126. let hex0String = "";
  127. for (let i = 0; i < 8 - valueAsHex.length; i++) { //padding the '0's
  128. hex0String += "0";
  129. }
  130. valueAsHex = "0x" + hex0String + valueAsHex.toUpperCase();
  131. }
  132. else
  133. {
  134. valueAsHex = this.state.value;
  135. }
  136. return (
  137. <div>
  138. {
  139. !this.props.useEuler &&
  140. <div className={this.props.additionalClass ? this.props.additionalClass + " floatLine" : "floatLine"}>
  141. <div className="label" title={this.props.label}>
  142. {this.props.label}
  143. </div>
  144. <div className="value">
  145. <input type="string" className="hex-input" value={valueAsHex} onBlur={() => this.unlock()} onFocus={() => this.lock()}
  146. onChange={evt => this.updateValue(evt.target.value, false)}
  147. onKeyDown={evt => {
  148. if (evt.keyCode !== 13) {
  149. return;
  150. }
  151. this.updateValue(this.state.value, true);
  152. }}
  153. />
  154. </div>
  155. </div>
  156. }
  157. </div>
  158. );
  159. }
  160. }