customEditor.html 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6. <title>Editor</title>
  7. </head>
  8. <body>
  9. <h1>Custom Editor Instance</h1>
  10. <p>This is an example of creating a custom editor. You can edit the elements below and if you hit save, it will update the source file.</p>
  11. <div>
  12. <div style="float:left">
  13. <select style="width:190px;height:400px" id="npc_list" size="10"></select>
  14. </div>
  15. <div style="margin-left:200px">
  16. <p>Name
  17. <br/>
  18. <input type="text" id="npc_name" />
  19. </p>
  20. <p>Conversation Text
  21. <br/>
  22. <textarea id="convo_text" rows="10" cols="80"></textarea>
  23. </p>
  24. <div>
  25. <label>
  26. <input type="checkbox" value="quest_giver" id="quest">&nbsp;Quest Giver?
  27. </label>
  28. </div>
  29. </div>
  30. </div>
  31. <script>
  32. var filename;
  33. var structure;
  34. var currentObject;
  35. //get a reference to the elements
  36. var controls = {
  37. list: document.getElementById("npc_list"),
  38. npcName: document.getElementById("npc_name"),
  39. convoText: document.getElementById("convo_text"),
  40. questCheck: document.getElementById("quest")
  41. };
  42. controls.convoText.addEventListener("input", (event) => {
  43. if (currentObject) {
  44. atomicQueryPromise("editorChange");
  45. currentObject.convo = controls.convoText.value;
  46. }
  47. event.stopPropagation();
  48. });
  49. controls.npcName.addEventListener("input", (event) => {
  50. if (currentObject) {
  51. atomicQueryPromise("editorChange");
  52. currentObject.name = controls.npcName.value;
  53. controls.list.options[controls.list.selectedIndex].text = currentObject.name;
  54. }
  55. event.stopPropagation();
  56. });
  57. controls.questCheck.addEventListener("click", (event) => {
  58. if (currentObject) {
  59. atomicQueryPromise("editorChange");
  60. currentObject.quest_giver = event.currentTarget.checked;
  61. }
  62. event.stopPropagation();
  63. });
  64. controls.list.addEventListener("change", (event) => {
  65. var selName = controls.list.options[controls.list.selectedIndex].text;
  66. currentObject = structure.npclist.find((el) => el.name == selName);
  67. if (currentObject) {
  68. controls.convoText.value = currentObject.convo;
  69. controls.npcName.value = currentObject.name;
  70. controls.questCheck.checked = currentObject.quest_giver;
  71. }
  72. event.stopPropagation();
  73. });
  74. /**
  75. * Promise version of atomic query
  76. * @param {string} message the query to use to pass to atomicQuery. If there is no payload, this will be passed directly, otherwise it will be passed in a data object
  77. * @param {any} payload optional data to send
  78. * @return {Promise}
  79. */
  80. function atomicQueryPromise(message) {
  81. return new Promise(function(resolve, reject) {
  82. var queryMessage = message;
  83. // if message is coming in as an object then let's stringify it
  84. if (typeof(message) != "string") {
  85. queryMessage = JSON.stringify(message);
  86. }
  87. window.atomicQuery({
  88. request: queryMessage,
  89. persistent: false,
  90. onSuccess: resolve,
  91. onFailure: (error_code, error_message) => reject({
  92. error_code: error_code,
  93. error_message: error_message
  94. })
  95. });
  96. });
  97. }
  98. /**
  99. * Queries the host for a particular resource and returns it in a promise
  100. * @param {string} codeUrl
  101. * @return {Promise}
  102. */
  103. function getResource(codeUrl) {
  104. return new Promise(function(resolve, reject) {
  105. var xmlHttp = new XMLHttpRequest();
  106. xmlHttp.onreadystatechange = () => {
  107. if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
  108. resolve(xmlHttp.responseText);
  109. }
  110. };
  111. xmlHttp.open("GET", codeUrl, true); // true for asynchronous
  112. xmlHttp.send(null);
  113. });
  114. }
  115. // Functions exposed to the host editor. These
  116. // are hooked in here so that they are available immediately from the host
  117. function HOST_loadCode(codeUrl) {
  118. // preferences are available on the window object as stringified JSON strings
  119. // in case they are needed
  120. var projectPrefs = JSON.parse(window.HOST_Preferences.ProjectPreferences);
  121. var applicationPrefs = JSON.parse(window.HOST_Preferences.ApplicationPreferences);
  122. filename = codeUrl.replace("atomic://", "");
  123. getResource(codeUrl).then((code) => {
  124. structure = JSON.parse(code);
  125. for (var i = 0; i < structure.npclist.length; i++) {
  126. var opt = document.createElement("OPTION");
  127. controls.list.options.add(opt);
  128. opt.text = structure.npclist[i].name;
  129. }
  130. });
  131. }
  132. function HOST_saveCode() {
  133. atomicQueryPromise({
  134. message: "editorSaveCode",
  135. payload: JSON.stringify(structure, null, 2)
  136. });
  137. }
  138. function HOST_resourceRenamed(path, newPath) {
  139. alert("Resource Renamed: " + path + "->" + newPath);
  140. }
  141. function HOST_resourceDeleted(path) {
  142. alert("Resource Deleted: " + path);
  143. }
  144. function HOST_preferencesChanged() {
  145. // Updated preferences are available on the window object as stringified JSON strings
  146. var projectPrefs = JSON.parse(window.HOST_Preferences.ProjectPreferences);
  147. var applicationPrefs = JSON.parse(window.HOST_Preferences.ApplicationPreferences);
  148. alert("Prefs Changed.");
  149. }
  150. </script>
  151. </body>
  152. </html>