editorControls.tsx 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. import * as React from "react";
  2. import { Observable } from "babylonjs/Misc/observable";
  3. import { PropertyChangedEvent } from "../../../../../components/propertyChangedEvent";
  4. import { Animation } from "babylonjs/Animations/animation";
  5. import { IconButtonLineComponent } from "../../../lines/iconButtonLineComponent";
  6. import { NumericInputComponent } from "../../../lines/numericInputComponent";
  7. import { AddAnimation } from "./addAnimation";
  8. import { AnimationListTree, SelectedCoordinate } from "./animationListTree";
  9. import { IAnimatable } from "babylonjs/Animations/animatable.interface";
  10. import { TargetedAnimation } from "babylonjs/Animations/animationGroup";
  11. import { LoadSnippet } from "./loadsnippet";
  12. import { SaveSnippet } from "./saveSnippet";
  13. import { LockObject } from "../lockObject";
  14. interface IEditorControlsProps {
  15. isTargetedAnimation: boolean;
  16. entity: IAnimatable | TargetedAnimation;
  17. selected: Animation | null;
  18. lockObject: LockObject;
  19. onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
  20. setNotificationMessage: (message: string) => void;
  21. selectAnimation: (selected: Animation, axis?: SelectedCoordinate) => void;
  22. }
  23. export class EditorControls extends React.Component<
  24. IEditorControlsProps,
  25. {
  26. isAnimationTabOpen: boolean;
  27. isEditTabOpen: boolean;
  28. isLoadTabOpen: boolean;
  29. isSaveTabOpen: boolean;
  30. isLoopActive: boolean;
  31. animationsCount: number;
  32. framesPerSecond: number;
  33. }
  34. > {
  35. constructor(props: IEditorControlsProps) {
  36. super(props);
  37. let count = this.props.isTargetedAnimation
  38. ? 1
  39. : (this.props.entity as IAnimatable).animations?.length ?? 0;
  40. this.state = {
  41. isAnimationTabOpen: count === 0 ? true : false,
  42. isEditTabOpen: count === 0 ? false : true,
  43. isSaveTabOpen: false,
  44. isLoadTabOpen: false,
  45. isLoopActive: false,
  46. animationsCount: count,
  47. framesPerSecond: 60,
  48. };
  49. }
  50. animationAdded() {
  51. this.setState({
  52. animationsCount: this.recountAnimations(),
  53. isEditTabOpen: true,
  54. isAnimationTabOpen: false,
  55. });
  56. }
  57. recountAnimations() {
  58. return (this.props.entity as IAnimatable).animations?.length ?? 0;
  59. }
  60. handleTabs(tab: number) {
  61. let state = {
  62. isAnimationTabOpen: true,
  63. isLoadTabOpen: false,
  64. isSaveTabOpen: false,
  65. isEditTabOpen: false,
  66. };
  67. switch (tab) {
  68. case 0:
  69. state = {
  70. isAnimationTabOpen: true,
  71. isLoadTabOpen: false,
  72. isSaveTabOpen: false,
  73. isEditTabOpen: false,
  74. };
  75. break;
  76. case 1:
  77. state = {
  78. isAnimationTabOpen: false,
  79. isLoadTabOpen: true,
  80. isSaveTabOpen: false,
  81. isEditTabOpen: false,
  82. };
  83. break;
  84. case 2:
  85. state = {
  86. isAnimationTabOpen: false,
  87. isLoadTabOpen: false,
  88. isSaveTabOpen: true,
  89. isEditTabOpen: false,
  90. };
  91. break;
  92. case 3:
  93. state = {
  94. isAnimationTabOpen: false,
  95. isLoadTabOpen: false,
  96. isSaveTabOpen: false,
  97. isEditTabOpen: true,
  98. };
  99. break;
  100. }
  101. this.setState(state);
  102. }
  103. handleChangeFps(fps: number) {
  104. this.setState({ framesPerSecond: fps });
  105. }
  106. emptiedList() {
  107. this.setState({
  108. animationsCount: this.recountAnimations(),
  109. isEditTabOpen: false,
  110. isAnimationTabOpen: true,
  111. });
  112. }
  113. render() {
  114. return (
  115. <div className="animation-list">
  116. <div className="controls-header">
  117. {this.props.isTargetedAnimation ? null : (
  118. <IconButtonLineComponent
  119. active={this.state.isAnimationTabOpen}
  120. tooltip="Add Animation"
  121. icon="medium add-animation"
  122. onClick={() => this.handleTabs(0)}
  123. ></IconButtonLineComponent>
  124. )}
  125. <IconButtonLineComponent
  126. active={this.state.isLoadTabOpen}
  127. tooltip="Load Animation"
  128. icon="medium load"
  129. onClick={() => this.handleTabs(1)}
  130. ></IconButtonLineComponent>
  131. <IconButtonLineComponent
  132. active={this.state.isSaveTabOpen}
  133. tooltip="Save Animation"
  134. icon="medium save"
  135. onClick={() => this.handleTabs(2)}
  136. ></IconButtonLineComponent>
  137. {this.state.animationsCount === 0 ? null : (
  138. <IconButtonLineComponent
  139. active={this.state.isEditTabOpen}
  140. tooltip="Edit Animations"
  141. icon="medium animation-edit"
  142. onClick={() => this.handleTabs(3)}
  143. ></IconButtonLineComponent>
  144. )}
  145. {this.state.isEditTabOpen ? (
  146. <div className="input-fps">
  147. <NumericInputComponent
  148. label={""}
  149. precision={0}
  150. value={this.state.framesPerSecond}
  151. onChange={(framesPerSecond: number) =>
  152. this.handleChangeFps(framesPerSecond)
  153. }
  154. />
  155. <p>fps</p>
  156. </div>
  157. ) : null}
  158. {this.state.isEditTabOpen ? (
  159. <IconButtonLineComponent
  160. tooltip="Loop/Unloop"
  161. icon={`medium ${
  162. this.state.isLoopActive
  163. ? "loop-active last"
  164. : "loop-inactive last"
  165. }`}
  166. onClick={() => {
  167. this.setState({ isLoopActive: !this.state.isLoopActive });
  168. }}
  169. ></IconButtonLineComponent>
  170. ) : null}
  171. </div>
  172. {this.props.isTargetedAnimation ? null : (
  173. <AddAnimation
  174. isOpen={this.state.isAnimationTabOpen}
  175. close={() => {
  176. this.setState({ isAnimationTabOpen: false });
  177. }}
  178. entity={this.props.entity as IAnimatable}
  179. setNotificationMessage={(message: string) => {
  180. this.props.setNotificationMessage(message);
  181. }}
  182. changed={() => this.animationAdded()}
  183. onPropertyChangedObservable={this.props.onPropertyChangedObservable}
  184. />
  185. )}
  186. {this.state.isLoadTabOpen ? (
  187. <LoadSnippet lockObject={this.props.lockObject} animations={[]} />
  188. ) : null}
  189. {this.state.isSaveTabOpen ? (
  190. <SaveSnippet lockObject={this.props.lockObject} animations={[]} />
  191. ) : null}
  192. {this.state.isEditTabOpen ? (
  193. <AnimationListTree
  194. isTargetedAnimation={this.props.isTargetedAnimation}
  195. entity={this.props.entity}
  196. selected={this.props.selected}
  197. onPropertyChangedObservable={this.props.onPropertyChangedObservable}
  198. empty={() => this.emptiedList()}
  199. selectAnimation={this.props.selectAnimation}
  200. />
  201. ) : null}
  202. </div>
  203. );
  204. }
  205. }