vector2LineComponent.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import * as React from "react";
  2. import { Vector2 } from "babylonjs/Maths/math.vector";
  3. import { Observable } from "babylonjs/Misc/observable";
  4. import { NumericInputComponent } from "./numericInputComponent";
  5. import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
  6. import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
  7. import { PropertyChangedEvent } from "./propertyChangedEvent";
  8. import { GlobalState } from '../globalState';
  9. interface IVector2LineComponentProps {
  10. label: string;
  11. target: any;
  12. propertyName: string;
  13. step?: number;
  14. onChange?: (newvalue: Vector2) => void;
  15. onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
  16. globalState: GlobalState;
  17. }
  18. export class Vector2LineComponent extends React.Component<IVector2LineComponentProps, { isExpanded: boolean, value: Vector2 }> {
  19. static defaultProps = {
  20. step: 0.001, // cm
  21. };
  22. private _localChange = false;
  23. constructor(props: IVector2LineComponentProps) {
  24. super(props);
  25. this.state = { isExpanded: false, value: this.props.target[this.props.propertyName].clone() }
  26. }
  27. shouldComponentUpdate(nextProps: IVector2LineComponentProps, nextState: { isExpanded: boolean, value: Vector2 }) {
  28. const nextPropsValue = nextProps.target[nextProps.propertyName];
  29. if (!nextPropsValue.equals(nextState.value) || this._localChange) {
  30. nextState.value = nextPropsValue.clone();
  31. this._localChange = false;
  32. return true;
  33. }
  34. return false;
  35. }
  36. switchExpandState() {
  37. this._localChange = true;
  38. this.setState({ isExpanded: !this.state.isExpanded });
  39. }
  40. raiseOnPropertyChanged(previousValue: Vector2) {
  41. if (this.props.onChange) {
  42. this.props.onChange(this.state.value);
  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: this.state.value,
  51. initialValue: previousValue
  52. });
  53. }
  54. updateStateX(value: number) {
  55. this._localChange = true;
  56. const store = this.state.value.clone();
  57. this.props.target[this.props.propertyName].x = value;
  58. this.state.value.x = value;
  59. this.setState({ value: this.state.value });
  60. this.raiseOnPropertyChanged(store);
  61. }
  62. updateStateY(value: number) {
  63. this._localChange = true;
  64. const store = this.state.value.clone();
  65. this.props.target[this.props.propertyName].y = value;
  66. this.state.value.y = value;
  67. this.setState({ value: this.state.value });
  68. this.raiseOnPropertyChanged(store);
  69. }
  70. render() {
  71. const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />
  72. return (
  73. <div className="vector3Line">
  74. <div className="firstLine">
  75. <div className="label">
  76. {this.props.label}
  77. </div>
  78. <div className="vector">
  79. {`X: ${this.state.value.x.toFixed(2)}, Y: ${this.state.value.y.toFixed(2)}`}
  80. </div>
  81. <div className="expand hoverIcon" onClick={() => this.switchExpandState()} title="Expand">
  82. {chevron}
  83. </div>
  84. </div>
  85. {
  86. this.state.isExpanded &&
  87. <div className="secondLine">
  88. <NumericInputComponent globalState={this.props.globalState} label="x" step={this.props.step} value={this.state.value.x} onChange={value => this.updateStateX(value)} />
  89. <NumericInputComponent globalState={this.props.globalState} label="y" step={this.props.step} value={this.state.value.y} onChange={value => this.updateStateY(value)} />
  90. </div>
  91. }
  92. </div>
  93. );
  94. }
  95. }