Home Reference Source

cables_dev/cables_electron/src_client/cmd_electron.js

  1. import pako from "pako";
  2. import cablesElectron from "./renderer.js";
  3. const CABLES_CMD_ELECTRON = {};
  4. const CABLES_CMD_ELECTRON_OVERRIDES = {};
  5. const CMD_ELECTRON_COMMANDS = [];
  6. function bytesArrToBase64(arr)
  7. {
  8. const abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // base64 alphabet
  9. const bin = (n) => { return n.toString(2).padStart(8, 0); }; // convert num to 8-bit binary string
  10. const l = arr.length;
  11. let result = "";
  12. for (let i = 0; i <= (l - 1) / 3; i++)
  13. {
  14. let c1 = i * 3 + 1 >= l; // case when "=" is on end
  15. let c2 = i * 3 + 2 >= l; // case when "=" is on end
  16. let chunk = bin(arr[3 * i]) + bin(c1 ? 0 : arr[3 * i + 1]) + bin(c2 ? 0 : arr[3 * i + 2]);
  17. let r = chunk.match(/.{1,6}/g).map((x, j) => { return (j == 3 && c2 ? "=" : (j == 2 && c1 ? "=" : abc[+("0b" + x)])); });
  18. result += r.join("");
  19. }
  20. return result;
  21. }
  22. CABLES_CMD_ELECTRON.openOpDir = (opId = null, opName = null) =>
  23. {
  24. const gui = cablesElectron.gui;
  25. if (gui)
  26. {
  27. let options = { "opId": opId, "opName": opName };
  28. if (!opId && !opName)
  29. {
  30. const ops = gui.patchView.getSelectedOps();
  31. if (!ops.length) return;
  32. options = {
  33. "opId": ops[0].opId,
  34. "opName": ops[0].name
  35. };
  36. }
  37. cablesElectron.editor.api("openOpDir", options, (_err, r) => {});
  38. }
  39. };
  40. CABLES_CMD_ELECTRON.openProjectDir = () =>
  41. {
  42. cablesElectron.editor.api("openProjectDir", {}, (_err, r) => {});
  43. };
  44. CABLES_CMD_ELECTRON.openFileManager = (url = null) =>
  45. {
  46. const data = {};
  47. if (url) data.url = url;
  48. cablesElectron.editor.api("openFileManager", data, (_err, r) => {});
  49. };
  50. CABLES_CMD_ELECTRON.collectAssets = () =>
  51. {
  52. const loadingModal = cablesElectron.gui.startModalLoading("Copying assets...");
  53. let closeTimeout = 2000;
  54. cablesElectron.editor.api("collectAssets", {}, (_err, r) =>
  55. {
  56. if (!_err)
  57. {
  58. const ops = cablesElectron.gui.corePatch().ops;
  59. const oldNew = r.data;
  60. if (oldNew)
  61. {
  62. const assetPorts = [];
  63. for (let i = 0; i < ops.length; i++)
  64. {
  65. for (let j = 0; j < ops[i].portsIn.length; j++)
  66. {
  67. if (ops[i].portsIn[j].uiAttribs && ops[i].portsIn[j].uiAttribs.display && ops[i].portsIn[j].uiAttribs.display === "file")
  68. {
  69. assetPorts.push(ops[i].portsIn[j]);
  70. }
  71. }
  72. }
  73. const oldNames = Object.keys(oldNew);
  74. if (oldNames.length > 0)
  75. {
  76. oldNames.forEach((srch) =>
  77. {
  78. const rplc = oldNew[srch];
  79. loadingModal.setTask("copied " + srch + " to " + rplc);
  80. assetPorts.forEach((assetPort) =>
  81. {
  82. let v = assetPort.get();
  83. if (v && v.startsWith(srch))
  84. {
  85. v = rplc + v.substring(srch.length);
  86. assetPort.set(v);
  87. }
  88. });
  89. });
  90. cablesElectron.gui.setStateUnsaved();
  91. }
  92. else
  93. {
  94. loadingModal.setTask("nothing to copy");
  95. }
  96. }
  97. else
  98. {
  99. loadingModal.setTask("nothing to copy");
  100. }
  101. }
  102. else
  103. {
  104. loadingModal.setTask("failed to copy assets");
  105. loadingModal.setTask("---");
  106. loadingModal.setTask(_err);
  107. closeTimeout = 5000;
  108. }
  109. setTimeout(() => { cablesElectron.gui.endModalLoading(); }, closeTimeout);
  110. });
  111. };
  112. CABLES_CMD_ELECTRON.collectOps = () =>
  113. {
  114. const loadingModal = cablesElectron.gui.startModalLoading("Copying ops...");
  115. let closeTimeout = 2000;
  116. cablesElectron.editor.api("collectOps", { }, (_err, r) =>
  117. {
  118. if (!_err && r && r.data)
  119. {
  120. const oldNames = Object.keys(r.data);
  121. if (r && oldNames.length > 0)
  122. {
  123. oldNames.forEach((srch) =>
  124. {
  125. const rplc = r.data[srch];
  126. loadingModal.setTask("copied " + srch + " to " + rplc);
  127. });
  128. }
  129. else
  130. {
  131. loadingModal.setTask("nothing to copy");
  132. }
  133. setTimeout(() => { cablesElectron.gui.endModalLoading(); }, closeTimeout);
  134. }
  135. else
  136. {
  137. loadingModal.setTask("failed to copy ops");
  138. loadingModal.setTask("---");
  139. loadingModal.setTask(_err);
  140. closeTimeout = 5000;
  141. setTimeout(() => { cablesElectron.gui.endModalLoading(); }, closeTimeout);
  142. }
  143. });
  144. };
  145. CABLES_CMD_ELECTRON.manageOpDirs = () =>
  146. {
  147. cablesElectron.openOpDirsTab();
  148. };
  149. CABLES_CMD_ELECTRON.copyOpDirToClipboard = (opId = null) =>
  150. {
  151. const gui = cablesElectron.gui;
  152. if (gui)
  153. {
  154. if (!opId)
  155. {
  156. const ops = gui.patchView.getSelectedOps();
  157. if (!ops.length) return;
  158. opId = ops[0].opId;
  159. }
  160. const modulePath = window.ipcRenderer.sendSync("getOpDir", { "opId": opId });
  161. if (modulePath)
  162. {
  163. navigator.clipboard.writeText(modulePath);
  164. cablesElectron.editor.notify("Op path copied to clipboard");
  165. }
  166. }
  167. };
  168. CABLES_CMD_ELECTRON_OVERRIDES.PATCH = {};
  169. CABLES_CMD_ELECTRON_OVERRIDES.PATCH.saveAs = () =>
  170. {
  171. const gui = cablesElectron.gui;
  172. let patchName = cablesElectron.gui.project() ? cablesElectron.gui.project().name : null;
  173. let b64 = null;
  174. if (gui)
  175. {
  176. const patch = cablesElectron.gui.patchView.store.makePatchSavable();
  177. const patchstr = JSON.stringify(patch);
  178. let uint8data = pako.deflate(patchstr);
  179. b64 = bytesArrToBase64(uint8data);
  180. }
  181. cablesElectron.editor.api("saveProjectAs", {
  182. "name": patchName,
  183. "dataB64": b64
  184. }, (err) =>
  185. {
  186. if (!err && gui)
  187. {
  188. gui.savedState.setSaved("save as end", 0);
  189. }
  190. });
  191. };
  192. CABLES_CMD_ELECTRON_OVERRIDES.PATCH.uploadFileDialog = () =>
  193. {
  194. cablesElectron.editor.api("selectFile", {}, (_err, filepath) =>
  195. {
  196. if (!_err && filepath)
  197. {
  198. const gui = cablesElectron.gui;
  199. if (gui) gui.patchView.addAssetOpAuto(filepath);
  200. }
  201. });
  202. };
  203. CABLES_CMD_ELECTRON_OVERRIDES.PATCH.newPatch = () =>
  204. {
  205. cablesElectron.editor.api("newPatch", { }, (_err, r) => {});
  206. };
  207. CABLES_CMD_ELECTRON_OVERRIDES.PATCH.renameOp = (opName = null) =>
  208. {
  209. const gui = cablesElectron.gui;
  210. if (gui)
  211. {
  212. if (!opName)
  213. {
  214. const ops = gui.patchView.getSelectedOps();
  215. if (!ops.length) return;
  216. const op = ops[0];
  217. opName = op.objName;
  218. }
  219. gui.serverOps.renameDialog(opName);
  220. }
  221. };
  222. CABLES_CMD_ELECTRON_OVERRIDES.RENDERER = {};
  223. CABLES_CMD_ELECTRON_OVERRIDES.RENDERER.fullscreen = () =>
  224. {
  225. cablesElectron.editor.api("cycleFullscreen", { }, (_err, r) => {});
  226. };
  227. CABLES_CMD_ELECTRON_OVERRIDES.UI = {};
  228. CABLES_CMD_ELECTRON_OVERRIDES.UI.windowFullscreen = () =>
  229. {
  230. cablesElectron.editor.api("cycleFullscreen", { }, (_err, r) => {});
  231. };
  232. const CABLES_CMD_COMMAND_OVERRIDES = [
  233. {
  234. "cmd": "save patch as...",
  235. "func": CABLES_CMD_ELECTRON_OVERRIDES.PATCH.saveAs
  236. },
  237. {
  238. "cmd": "upload file dialog",
  239. "func": CABLES_CMD_ELECTRON_OVERRIDES.PATCH.uploadFileDialog
  240. },
  241. {
  242. "cmd": "create new patch",
  243. "func": CABLES_CMD_ELECTRON_OVERRIDES.PATCH.newPatch
  244. },
  245. {
  246. "cmd": "rename op",
  247. "func": CABLES_CMD_ELECTRON_OVERRIDES.PATCH.renameOp
  248. },
  249. {
  250. "cmd": "Toggle window fullscreen",
  251. "func": CABLES_CMD_ELECTRON_OVERRIDES.UI.windowFullscreen
  252. }
  253. ];
  254. CMD_ELECTRON_COMMANDS.push(
  255. {
  256. "cmd": "collect assets into patch dir",
  257. "category": "patch",
  258. "func": CABLES_CMD_ELECTRON.collectAssets,
  259. "icon": "file"
  260. },
  261. {
  262. "cmd": "collect ops into patch dir",
  263. "category": "ops",
  264. "func": CABLES_CMD_ELECTRON.collectOps,
  265. "icon": "op"
  266. },
  267. {
  268. "cmd": "manage op directories",
  269. "category": "ops",
  270. "func": CABLES_CMD_ELECTRON.manageOpDirs,
  271. "icon": "folder"
  272. },
  273. {
  274. "cmd": "install ops from package.json",
  275. "category": "ops",
  276. "func": CABLES_CMD_ELECTRON.addOpPackage,
  277. "icon": "op"
  278. },
  279. {
  280. "cmd": "copy op dir to clipboard",
  281. "category": "ops",
  282. "func": CABLES_CMD_ELECTRON.copyOpDirToClipboard,
  283. "icon": "op"
  284. },
  285. {
  286. "cmd": "open op directory",
  287. "category": "ops",
  288. "func": CABLES_CMD_ELECTRON.openOpDir,
  289. "icon": "folder"
  290. },
  291. {
  292. "cmd": "open project directory",
  293. "category": "patch",
  294. "func": CABLES_CMD_ELECTRON.openProjectDir,
  295. "icon": "folder"
  296. },
  297. {
  298. "cmd": "open os file manager",
  299. "category": "cables",
  300. "func": CABLES_CMD_ELECTRON.openFileManager,
  301. "icon": "folder"
  302. }
  303. );
  304. export default {
  305. "commands": CMD_ELECTRON_COMMANDS,
  306. "functions": CABLES_CMD_ELECTRON,
  307. "functionOverrides": CABLES_CMD_ELECTRON_OVERRIDES,
  308. "commandOverrides": CABLES_CMD_COMMAND_OVERRIDES,
  309. };