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