spriteManagerPropertyGridComponent.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import * as React from "react";
  2. import { Observable } from "babylonjs/Misc/observable";
  3. import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
  4. import { LockObject } from "../../../../../sharedUiComponents/tabs/propertyGrids/lockObject";
  5. import { LineContainerComponent } from '../../../lineContainerComponent';
  6. import { GlobalState } from '../../../../globalState';
  7. import { SpriteManager } from 'babylonjs/Sprites/spriteManager';
  8. import { TextInputLineComponent } from '../../../../../sharedUiComponents/lines/textInputLineComponent';
  9. import { TextLineComponent } from '../../../../../sharedUiComponents/lines/textLineComponent';
  10. import { CheckBoxLineComponent } from '../../../../../sharedUiComponents/lines/checkBoxLineComponent';
  11. import { FloatLineComponent } from '../../../../../sharedUiComponents/lines/floatLineComponent';
  12. import { SliderLineComponent } from '../../../../../sharedUiComponents/lines/sliderLineComponent';
  13. import { RenderingManager } from 'babylonjs/Rendering/renderingManager';
  14. import { TextureLinkLineComponent } from '../../../lines/textureLinkLineComponent';
  15. import { ButtonLineComponent } from '../../../../../sharedUiComponents/lines/buttonLineComponent';
  16. import { Sprite } from 'babylonjs/Sprites/sprite';
  17. import { Tools } from 'babylonjs/Misc/tools';
  18. import { FileButtonLineComponent } from '../../../../../sharedUiComponents/lines/fileButtonLineComponent';
  19. import { Constants } from 'babylonjs/Engines/constants';
  20. import { OptionsLineComponent } from '../../../../../sharedUiComponents/lines/optionsLineComponent';
  21. interface ISpriteManagerPropertyGridComponentProps {
  22. globalState: GlobalState;
  23. spriteManager: SpriteManager;
  24. lockObject: LockObject;
  25. onSelectionChangedObservable?: Observable<any>;
  26. onPropertyChangedObservable?: Observable<PropertyChangedEvent>
  27. }
  28. export class SpriteManagerPropertyGridComponent extends React.Component<ISpriteManagerPropertyGridComponentProps> {
  29. private _snippetUrl = "https://snippet.babylonjs.com";
  30. constructor(props: ISpriteManagerPropertyGridComponentProps) {
  31. super(props);
  32. }
  33. addNewSprite() {
  34. const spriteManager = this.props.spriteManager;
  35. var newSprite = new Sprite("new sprite", spriteManager);
  36. this.props.onSelectionChangedObservable?.notifyObservers(newSprite);
  37. }
  38. disposeManager() {
  39. const spriteManager = this.props.spriteManager;
  40. spriteManager.dispose();
  41. this.props.onSelectionChangedObservable?.notifyObservers(null);
  42. }
  43. saveToFile() {
  44. const spriteManager = this.props.spriteManager;
  45. let content = JSON.stringify(spriteManager.serialize(true));
  46. Tools.Download(new Blob([content]), "spriteManager.json");
  47. }
  48. loadFromFile(file: File) {
  49. const spriteManager = this.props.spriteManager;
  50. const scene = spriteManager.scene;
  51. Tools.ReadFile(file, (data) => {
  52. let decoder = new TextDecoder("utf-8");
  53. let jsonObject = JSON.parse(decoder.decode(data));
  54. spriteManager.dispose();
  55. this.props.globalState.onSelectionChangedObservable.notifyObservers(null);
  56. let newManager = SpriteManager.Parse(jsonObject, scene, "");
  57. this.props.globalState.onSelectionChangedObservable.notifyObservers(newManager);
  58. }, undefined, true);
  59. }
  60. loadFromSnippet() {
  61. const spriteManager = this.props.spriteManager;
  62. const scene = spriteManager.scene;
  63. let snippedID = window.prompt("Please enter the snippet ID to use");
  64. if (!snippedID) {
  65. return;
  66. }
  67. spriteManager.dispose();
  68. this.props.globalState.onSelectionChangedObservable.notifyObservers(null);
  69. SpriteManager.CreateFromSnippetAsync(snippedID, scene).then((newManager) => {
  70. this.props.globalState.onSelectionChangedObservable.notifyObservers(newManager);
  71. }).catch(err => {
  72. alert("Unable to load your sprite manager: " + err);
  73. });
  74. }
  75. saveToSnippet() {
  76. const spriteManager = this.props.spriteManager;
  77. let content = JSON.stringify(spriteManager.serialize(true));
  78. var xmlHttp = new XMLHttpRequest();
  79. xmlHttp.onreadystatechange = () => {
  80. if (xmlHttp.readyState == 4) {
  81. if (xmlHttp.status == 200) {
  82. var snippet = JSON.parse(xmlHttp.responseText);
  83. const oldId = spriteManager.snippetId || "_BLANK";
  84. spriteManager.snippetId = snippet.id;
  85. if (snippet.version && snippet.version != "0") {
  86. spriteManager.snippetId += "#" + snippet.version;
  87. }
  88. this.forceUpdate();
  89. if (navigator.clipboard) {
  90. navigator.clipboard.writeText(spriteManager.snippetId);
  91. }
  92. let windowAsAny = window as any;
  93. if (windowAsAny.Playground && oldId) {
  94. windowAsAny.Playground.onRequestCodeChangeObservable.notifyObservers({
  95. regex: new RegExp(`SpriteManager.CreateFromSnippetAsync\\("${oldId}`, "g"),
  96. replace: `SpriteManager.CreateFromSnippetAsync("${spriteManager.snippetId}`
  97. });
  98. }
  99. alert("Sprite manager saved with ID: " + spriteManager.snippetId + " (please note that the id was also saved to your clipboard)");
  100. }
  101. else {
  102. alert("Unable to save your sprite manager");
  103. }
  104. }
  105. }
  106. xmlHttp.open("POST", this._snippetUrl + (spriteManager.snippetId ? "/" + spriteManager.snippetId : ""), true);
  107. xmlHttp.setRequestHeader("Content-Type", "application/json");
  108. var dataToSend = {
  109. payload : JSON.stringify({
  110. spriteManager: content
  111. }),
  112. name: "",
  113. description: "",
  114. tags: ""
  115. };
  116. xmlHttp.send(JSON.stringify(dataToSend));
  117. }
  118. render() {
  119. const spriteManager = this.props.spriteManager;
  120. var alphaModeOptions = [
  121. { label: "Combine", value: Constants.ALPHA_COMBINE },
  122. { label: "One one", value: Constants.ALPHA_ONEONE },
  123. { label: "Add", value: Constants.ALPHA_ADD },
  124. { label: "Subtract", value: Constants.ALPHA_SUBTRACT },
  125. { label: "Multiply", value: Constants.ALPHA_MULTIPLY },
  126. { label: "Maximized", value: Constants.ALPHA_MAXIMIZED },
  127. { label: "Pre-multiplied", value: Constants.ALPHA_PREMULTIPLIED },
  128. ];
  129. return (
  130. <div className="pane">
  131. <LineContainerComponent globalState={this.props.globalState} title="GENERAL">
  132. <TextInputLineComponent lockObject={this.props.lockObject} label="Name" target={spriteManager} propertyName="name" onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
  133. <TextLineComponent label="Unique ID" value={spriteManager.uniqueId.toString()} />
  134. <TextLineComponent label="Capacity" value={spriteManager.capacity.toString()} />
  135. <TextureLinkLineComponent label="Texture" texture={spriteManager.texture} onSelectionChangedObservable={this.props.onSelectionChangedObservable}/>
  136. {
  137. spriteManager.sprites.length < spriteManager.capacity &&
  138. <ButtonLineComponent label="Add new sprite" onClick={() => this.addNewSprite()} />
  139. }
  140. <ButtonLineComponent label="Dispose" onClick={() => this.disposeManager()} />
  141. </LineContainerComponent>
  142. <LineContainerComponent globalState={this.props.globalState} title="FILE">
  143. <FileButtonLineComponent label="Load" onClick={(file) => this.loadFromFile(file)} accept=".json" />
  144. <ButtonLineComponent label="Save" onClick={() => this.saveToFile()} />
  145. </LineContainerComponent>
  146. <LineContainerComponent globalState={this.props.globalState} title="SNIPPET">
  147. {
  148. spriteManager.snippetId &&
  149. <TextLineComponent label="Snippet ID" value={spriteManager.snippetId} />
  150. }
  151. <ButtonLineComponent label="Load from snippet server" onClick={() => this.loadFromSnippet()} />
  152. <ButtonLineComponent label="Save to snippet server" onClick={() => this.saveToSnippet()} />
  153. </LineContainerComponent>
  154. <LineContainerComponent globalState={this.props.globalState} title="PROPERTIES">
  155. <CheckBoxLineComponent label="Pickable" target={spriteManager} propertyName="isPickable" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  156. <CheckBoxLineComponent label="Fog enabled" target={spriteManager} propertyName="fogEnabled" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  157. <CheckBoxLineComponent label="No depth write" target={spriteManager} propertyName="disableDepthWrite" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  158. <SliderLineComponent label="Rendering group ID" decimalCount={0} target={spriteManager} propertyName="renderingGroupId" minimum={RenderingManager.MIN_RENDERINGGROUPS} maximum={RenderingManager.MAX_RENDERINGGROUPS - 1} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  159. <OptionsLineComponent label="Alpha mode" options={alphaModeOptions} target={spriteManager} propertyName="blendMode"
  160. onPropertyChangedObservable={this.props.onPropertyChangedObservable}
  161. onSelect={(value) => this.setState({ blendMode: value })} />
  162. </LineContainerComponent>
  163. <LineContainerComponent globalState={this.props.globalState} title="CELLS">
  164. <FloatLineComponent label="Cell width" isInteger={true} target={spriteManager} propertyName="cellWidth" min={0} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
  165. <FloatLineComponent label="Cell height" isInteger={true} target={spriteManager} propertyName="cellHeight" min={0} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
  166. </LineContainerComponent>
  167. </div>
  168. );
  169. }
  170. }