actionTabsComponent.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import * as React from "react";
  2. import { Nullable } from "babylonjs/types";
  3. import { Observer } from "babylonjs/Misc/observable";
  4. import { Scene } from "babylonjs/scene";
  5. import { TabsComponent } from "./tabsComponent";
  6. import { faFileAlt, faWrench, faBug, faChartBar } from '@fortawesome/free-solid-svg-icons';
  7. import { StatisticsTabComponent } from "./tabs/statisticsTabComponent";
  8. import { DebugTabComponent } from "./tabs/debugTabComponent";
  9. import Resizable from "re-resizable";
  10. import { PropertyGridTabComponent } from "./tabs/propertyGridTabComponent";
  11. import { HeaderComponent } from "../headerComponent";
  12. import { ToolsTabComponent } from "./tabs/toolsTabComponent";
  13. import { GlobalState } from "../../components/globalState";
  14. require("./actionTabs.scss");
  15. interface IActionTabsComponentProps {
  16. scene: Scene,
  17. noCommands?: boolean,
  18. noHeader?: boolean,
  19. noExpand?: boolean,
  20. noClose?: boolean,
  21. popupMode?: boolean,
  22. onPopup?: () => void,
  23. onClose?: () => void,
  24. globalState: GlobalState
  25. }
  26. export class ActionTabsComponent extends React.Component<IActionTabsComponentProps, { selectedEntity: any, selectedIndex: number }> {
  27. private _onSelectionChangeObserver: Nullable<Observer<any>>;
  28. private _onTabChangedObserver: Nullable<Observer<any>>;
  29. private _once = true;
  30. constructor(props: IActionTabsComponentProps) {
  31. super(props);
  32. let initialIndex = 0;
  33. const validationResutls = this.props.globalState.validationResults;
  34. if (validationResutls) {
  35. if (validationResutls.issues.numErrors || validationResutls.issues.numWarnings) {
  36. initialIndex = 3;
  37. }
  38. }
  39. this.state = { selectedEntity: null, selectedIndex: initialIndex }
  40. }
  41. componentWillMount() {
  42. this._onSelectionChangeObserver = this.props.globalState.onSelectionChangedObservable.add((entity) => {
  43. this.setState({ selectedEntity: entity, selectedIndex: 0 });
  44. });
  45. this._onTabChangedObserver = this.props.globalState.onTabChangedObservable.add(index => {
  46. this.setState({ selectedIndex: index });
  47. });
  48. }
  49. componentWillUnmount() {
  50. if (this._onSelectionChangeObserver) {
  51. this.props.globalState.onSelectionChangedObservable.remove(this._onSelectionChangeObserver);
  52. }
  53. if (this._onTabChangedObserver) {
  54. this.props.globalState.onTabChangedObservable.remove(this._onTabChangedObserver);
  55. }
  56. }
  57. changeSelectedTab(index: number) {
  58. this.props.globalState.onTabChangedObservable.notifyObservers(index);
  59. }
  60. renderContent() {
  61. return (
  62. <TabsComponent selectedIndex={this.state.selectedIndex} onSelectedIndexChange={(value) => this.changeSelectedTab(value)}>
  63. <PropertyGridTabComponent
  64. title="Properties" icon={faFileAlt} scene={this.props.scene} selectedEntity={this.state.selectedEntity}
  65. globalState={this.props.globalState}
  66. onSelectionChangedObservable={this.props.globalState.onSelectionChangedObservable}
  67. onPropertyChangedObservable={this.props.globalState.onPropertyChangedObservable} />
  68. <DebugTabComponent title="Debug" icon={faBug} scene={this.props.scene} globalState={this.props.globalState} />
  69. <StatisticsTabComponent title="Statistics" icon={faChartBar} scene={this.props.scene} globalState={this.props.globalState} />
  70. <ToolsTabComponent title="Tools" icon={faWrench} scene={this.props.scene} globalState={this.props.globalState} />
  71. </TabsComponent>
  72. )
  73. }
  74. onClose() {
  75. if (!this.props.onClose) {
  76. return;
  77. }
  78. this.props.onClose();
  79. }
  80. onPopup() {
  81. if (!this.props.onPopup) {
  82. return;
  83. }
  84. this.props.onPopup();
  85. }
  86. render() {
  87. if (this.props.popupMode) {
  88. return (
  89. <div id="actionTabs">
  90. {
  91. !this.props.noHeader &&
  92. <HeaderComponent title="INSPECTOR" handleBack={true} noClose={this.props.noClose} noExpand={this.props.noExpand} noCommands={this.props.noCommands} onClose={() => this.onClose()} onPopup={() => this.onPopup()} onSelectionChangedObservable={this.props.globalState.onSelectionChangedObservable} />
  93. }
  94. {this.renderContent()}
  95. </div>
  96. );
  97. }
  98. if (this._once) {
  99. this._once = false;
  100. // A bit hacky but no other way to force the initial width to 300px and not auto
  101. setTimeout(() => {
  102. const element = document.getElementById("actionTabs");
  103. if (!element) {
  104. return;
  105. }
  106. element.style.width = "300px";
  107. }, 150);
  108. }
  109. return (
  110. <Resizable id="actionTabs" minWidth={300} maxWidth={600} size={{ height: "100%" }} minHeight="100%" enable={{ top: false, right: false, bottom: false, left: true, topRight: false, bottomRight: false, bottomLeft: false, topLeft: false }}>
  111. {
  112. !this.props.noHeader &&
  113. <HeaderComponent title="INSPECTOR" handleBack={true} noClose={this.props.noClose} noExpand={this.props.noExpand} noCommands={this.props.noCommands} onClose={() => this.onClose()} onPopup={() => this.onPopup()} onSelectionChangedObservable={this.props.globalState.onSelectionChangedObservable} />
  114. }
  115. {this.renderContent()}
  116. </Resizable>
  117. );
  118. }
  119. }