editorControls.tsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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. // select recently created animation/first coordinate...
  52. this.setState({
  53. animationsCount: this.recountAnimations(),
  54. isEditTabOpen: true,
  55. isAnimationTabOpen: false,
  56. });
  57. }
  58. recountAnimations() {
  59. return (this.props.entity as IAnimatable).animations?.length ?? 0;
  60. }
  61. handleTabs(tab: number) {
  62. let state = {
  63. isAnimationTabOpen: true,
  64. isLoadTabOpen: false,
  65. isSaveTabOpen: false,
  66. isEditTabOpen: false,
  67. };
  68. switch (tab) {
  69. case 0:
  70. state = {
  71. isAnimationTabOpen: true,
  72. isLoadTabOpen: false,
  73. isSaveTabOpen: false,
  74. isEditTabOpen: false,
  75. };
  76. break;
  77. case 1:
  78. state = {
  79. isAnimationTabOpen: false,
  80. isLoadTabOpen: true,
  81. isSaveTabOpen: false,
  82. isEditTabOpen: false,
  83. };
  84. break;
  85. case 2:
  86. state = {
  87. isAnimationTabOpen: false,
  88. isLoadTabOpen: false,
  89. isSaveTabOpen: true,
  90. isEditTabOpen: false,
  91. };
  92. break;
  93. case 3:
  94. state = {
  95. isAnimationTabOpen: false,
  96. isLoadTabOpen: false,
  97. isSaveTabOpen: false,
  98. isEditTabOpen: true,
  99. };
  100. break;
  101. }
  102. this.setState(state);
  103. }
  104. handleChangeFps(fps: number) {
  105. this.setState({ framesPerSecond: fps });
  106. }
  107. emptiedList() {
  108. this.setState({
  109. animationsCount: this.recountAnimations(),
  110. isEditTabOpen: false,
  111. isAnimationTabOpen: true,
  112. });
  113. }
  114. render() {
  115. return (
  116. <div className='animation-list'>
  117. <div className='controls-header'>
  118. {this.props.isTargetedAnimation ? null : (
  119. <IconButtonLineComponent
  120. active={this.state.isAnimationTabOpen}
  121. tooltip='Add Animation'
  122. icon='medium add-animation'
  123. onClick={() => this.handleTabs(0)}
  124. ></IconButtonLineComponent>
  125. )}
  126. <IconButtonLineComponent
  127. active={this.state.isLoadTabOpen}
  128. tooltip='Load Animation'
  129. icon='medium load'
  130. onClick={() => this.handleTabs(1)}
  131. ></IconButtonLineComponent>
  132. <IconButtonLineComponent
  133. active={this.state.isSaveTabOpen}
  134. tooltip='Save Animation'
  135. icon='medium save'
  136. onClick={() => this.handleTabs(2)}
  137. ></IconButtonLineComponent>
  138. {this.state.animationsCount === 0 ? null : (
  139. <IconButtonLineComponent
  140. active={this.state.isEditTabOpen}
  141. tooltip='Edit Animations'
  142. icon='medium animation-edit'
  143. onClick={() => this.handleTabs(3)}
  144. ></IconButtonLineComponent>
  145. )}
  146. {this.state.isEditTabOpen ? (
  147. <div className='input-fps'>
  148. <NumericInputComponent
  149. label={''}
  150. precision={0}
  151. value={this.state.framesPerSecond}
  152. onChange={(framesPerSecond: number) =>
  153. this.handleChangeFps(framesPerSecond)
  154. }
  155. />
  156. <p>fps</p>
  157. </div>
  158. ) : null}
  159. {this.state.isEditTabOpen ? (
  160. <IconButtonLineComponent
  161. tooltip='Loop/Unloop'
  162. icon={`medium ${
  163. this.state.isLoopActive
  164. ? 'loop-active last'
  165. : 'loop-inactive last'
  166. }`}
  167. onClick={() => {
  168. this.setState({ isLoopActive: !this.state.isLoopActive });
  169. }}
  170. ></IconButtonLineComponent>
  171. ) : null}
  172. </div>
  173. {this.props.isTargetedAnimation ? null : (
  174. <AddAnimation
  175. isOpen={this.state.isAnimationTabOpen}
  176. close={() => {
  177. this.setState({ isAnimationTabOpen: false });
  178. }}
  179. entity={this.props.entity as IAnimatable}
  180. setNotificationMessage={(message: string) => {
  181. this.props.setNotificationMessage(message);
  182. }}
  183. changed={() => this.animationAdded()}
  184. onPropertyChangedObservable={this.props.onPropertyChangedObservable}
  185. />
  186. )}
  187. {this.state.isLoadTabOpen ? (
  188. <LoadSnippet lockObject={this.props.lockObject} animations={[]} />
  189. ) : null}
  190. {this.state.isSaveTabOpen ? (
  191. <SaveSnippet lockObject={this.props.lockObject} animations={[]} />
  192. ) : null}
  193. {this.state.isEditTabOpen ? (
  194. <AnimationListTree
  195. isTargetedAnimation={this.props.isTargetedAnimation}
  196. entity={this.props.entity}
  197. selected={this.props.selected}
  198. onPropertyChangedObservable={this.props.onPropertyChangedObservable}
  199. empty={() => this.emptiedList()}
  200. selectAnimation={this.props.selectAnimation}
  201. />
  202. ) : null}
  203. </div>
  204. );
  205. }
  206. }