Remove editor instances concept and clean up JS interop code

This commit is contained in:
Keavon Chambers
2024-04-29 03:31:39 -07:00
parent 597c96a7db
commit 19eb6ce0ab
25 changed files with 256 additions and 325 deletions

View File

@@ -15,12 +15,12 @@
import { createNodeGraphState } from "@graphite/state-providers/node-graph";
import { createPortfolioState } from "@graphite/state-providers/portfolio";
import { operatingSystem } from "@graphite/utility-functions/platform";
import type { createEditor } from "@graphite/wasm-communication/editor";
import { type Editor } from "@graphite/wasm-communication/editor";
import MainWindow from "@graphite/components/window/MainWindow.svelte";
// Graphite WASM editor instance
export let editor: ReturnType<typeof createEditor>;
// Graphite WASM editor
export let editor: Editor;
setContext("editor", editor);
// State provider systems
@@ -48,7 +48,7 @@
onMount(() => {
// Initialize certain setup tasks required by the editor backend to be ready for the user now that the frontend is ready
editor.instance.initAfterFrontendReady(operatingSystem());
editor.handle.initAfterFrontendReady(operatingSystem());
});
onDestroy(() => {

View File

@@ -252,7 +252,7 @@
// TODO: Replace this temporary solution that only works in Chromium-based browsers with the custom color sampler used by the Eyedropper tool
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (!(window as any).EyeDropper) {
editor.instance.eyedropperSampleForColorPicker();
editor.handle.eyedropperSampleForColorPicker();
return;
}

View File

@@ -127,14 +127,14 @@
const file = item.getAsFile();
if (file?.type.includes("svg")) {
const svgData = await file.text();
editor.instance.pasteSvg(svgData, e.clientX, e.clientY);
editor.handle.pasteSvg(svgData, e.clientX, e.clientY);
return;
}
if (file?.type.startsWith("image")) {
const imageData = await extractPixelData(file);
editor.instance.pasteImage(new Uint8Array(imageData.data), imageData.width, imageData.height, e.clientX, e.clientY);
editor.handle.pasteImage(new Uint8Array(imageData.data), imageData.width, imageData.height, e.clientX, e.clientY);
}
});
}
@@ -142,23 +142,23 @@
function panCanvasX(newValue: number) {
const delta = newValue - scrollbarPos.x;
scrollbarPos.x = newValue;
editor.instance.panCanvas(-delta * scrollbarMultiplier.x, 0);
editor.handle.panCanvas(-delta * scrollbarMultiplier.x, 0);
}
function panCanvasY(newValue: number) {
const delta = newValue - scrollbarPos.y;
scrollbarPos.y = newValue;
editor.instance.panCanvas(0, -delta * scrollbarMultiplier.y);
editor.handle.panCanvas(0, -delta * scrollbarMultiplier.y);
}
function pageX(delta: number) {
const move = delta < 0 ? 1 : -1;
editor.instance.panCanvasByFraction(move, 0);
editor.handle.panCanvasByFraction(move, 0);
}
function pageY(delta: number) {
const move = delta < 0 ? 1 : -1;
editor.instance.panCanvasByFraction(0, move);
editor.handle.panCanvasByFraction(0, move);
}
function canvasPointerDown(e: PointerEvent) {
@@ -290,7 +290,7 @@
export function triggerTextCommit() {
if (!textInput) return;
const textCleaned = textInputCleanup(textInput.innerText);
editor.instance.onChangeText(textCleaned);
editor.handle.onChangeText(textCleaned);
}
export async function displayEditableTextbox(displayEditableTextbox: DisplayEditableTextbox) {
@@ -314,7 +314,7 @@
textInput.oninput = () => {
if (!textInput) return;
editor.instance.updateBounds(textInputCleanup(textInput.innerText));
editor.handle.updateBounds(textInputCleanup(textInput.innerText));
};
textInputMatrix = displayEditableTextbox.transform;
const newFont = new FontFace("text-font", `url(${displayEditableTextbox.url})`);
@@ -371,8 +371,8 @@
const rgb = await updateEyedropperSamplingState(mousePosition, primaryColor, secondaryColor);
if (setColorChoice && rgb) {
if (setColorChoice === "Primary") editor.instance.updatePrimaryColor(...rgb, 1);
if (setColorChoice === "Secondary") editor.instance.updateSecondaryColor(...rgb, 1);
if (setColorChoice === "Primary") editor.handle.updatePrimaryColor(...rgb, 1);
if (setColorChoice === "Secondary") editor.handle.updateSecondaryColor(...rgb, 1);
}
});

View File

@@ -130,15 +130,15 @@
}
function toggleLayerVisibility(id: bigint) {
editor.instance.toggleLayerVisibility(id);
editor.handle.toggleLayerVisibility(id);
}
function toggleLayerLock(id: bigint) {
editor.instance.toggleLayerLock(id);
editor.handle.toggleLayerLock(id);
}
function handleExpandArrowClick(id: bigint) {
editor.instance.toggleLayerExpansion(id);
editor.handle.toggleLayerExpansion(id);
}
async function onEditLayerName(listing: LayerListingInfo) {
@@ -164,7 +164,7 @@
layers = layers;
const name = (e.target instanceof HTMLInputElement && e.target.value) || "";
editor.instance.setLayerName(listing.entry.id, name);
editor.handle.setLayerName(listing.entry.id, name);
listing.entry.name = name;
}
@@ -196,11 +196,11 @@
// Don't select while we are entering text to rename the layer
if (listing.editingName) return;
editor.instance.selectLayer(listing.entry.id, accel, shift);
editor.handle.selectLayer(listing.entry.id, accel, shift);
}
async function deselectAllLayers() {
editor.instance.deselectAllLayers();
editor.handle.deselectAllLayers();
}
function isNestingLayer(layerClassification: LayerClassification) {
@@ -322,7 +322,7 @@
const { select, insertParentId, insertIndex } = draggingData;
select?.();
editor.instance.moveLayerInTree(insertParentId, insertIndex);
editor.handle.moveLayerInTree(insertParentId, insertIndex);
}
draggingData = undefined;
fakeHighlight = undefined;

View File

@@ -363,7 +363,7 @@
// Alt-click sets the clicked node as previewed
if (lmb && e.altKey && nodeId !== undefined) {
editor.instance.togglePreview(nodeId);
editor.handle.togglePreview(nodeId);
}
// Clicked on a port dot
@@ -440,7 +440,7 @@
}
// Update the selection in the backend if it was modified
if (modifiedSelected) editor.instance.selectNodes(new BigUint64Array(updatedSelected));
if (modifiedSelected) editor.handle.selectNodes(new BigUint64Array(updatedSelected));
return;
}
@@ -449,7 +449,7 @@
if (lmb) {
previousSelection = $nodeGraph.selected;
// Clear current selection
if (!e.shiftKey) editor.instance.selectNodes(new BigUint64Array(0));
if (!e.shiftKey) editor.handle.selectNodes(new BigUint64Array(0));
const graphBounds = graph?.getBoundingClientRect();
boxSelection = { startX: e.x - (graphBounds?.x || 0), startY: e.y - (graphBounds?.y || 0), endX: e.x - (graphBounds?.x || 0), endY: e.y - (graphBounds?.y || 0) };
@@ -466,7 +466,7 @@
// const nodeId = node?.getAttribute("data-node") || undefined;
// if (nodeId !== undefined) {
// const id = BigInt(nodeId);
// editor.instance.enterNestedNetwork(id);
// editor.handle.enterNestedNetwork(id);
// }
}
@@ -510,7 +510,7 @@
completeBoxSelection();
boxSelection = undefined;
} else if ((e.buttons & 2) !== 0) {
editor.instance.selectNodes(new BigUint64Array(previousSelection));
editor.handle.selectNodes(new BigUint64Array(previousSelection));
boxSelection = undefined;
} else {
const graphBounds = graph?.getBoundingClientRect();
@@ -534,7 +534,7 @@
}
function completeBoxSelection() {
editor.instance.selectNodes(new BigUint64Array($nodeGraph.selected.concat($nodeGraph.nodes.filter((_, nodeIndex) => intersetNodeAABB(boxSelection, nodeIndex)).map((node) => node.id))));
editor.handle.selectNodes(new BigUint64Array($nodeGraph.selected.concat($nodeGraph.nodes.filter((_, nodeIndex) => intersetNodeAABB(boxSelection, nodeIndex)).map((node) => node.id))));
}
function showSelected(selected: bigint[], boxSelect: Box | undefined, node: bigint, nodeIndex: number): boolean {
@@ -542,7 +542,7 @@
}
function toggleLayerVisibility(id: bigint) {
editor.instance.toggleLayerVisibility(id);
editor.handle.toggleLayerVisibility(id);
}
function connectorToNodeIndex(svg: SVGSVGElement): { nodeId: bigint; index: number } | undefined {
@@ -589,7 +589,7 @@
const selectedNodeBounds = selectedNode.getBoundingClientRect();
const containerBoundsBounds = theNodesContainer.getBoundingClientRect();
return editor.instance.rectangleIntersects(
return editor.handle.rectangleIntersects(
new Float64Array(wireCurveLocations.map((loc) => loc.x)),
new Float64Array(wireCurveLocations.map((loc) => loc.y)),
selectedNodeBounds.top - containerBoundsBounds.y,
@@ -603,9 +603,9 @@
if (link) {
const isLayer = $nodeGraph.nodes.find((n) => n.id === selectedNodeId)?.isLayer;
editor.instance.connectNodesByLink(link.linkStart, 0, selectedNodeId, isLayer ? 1 : 0);
editor.instance.connectNodesByLink(selectedNodeId, 0, link.linkEnd, Number(link.linkEndInputIndex));
if (!isLayer) editor.instance.shiftNode(selectedNodeId);
editor.handle.connectNodesByLink(link.linkStart, 0, selectedNodeId, isLayer ? 1 : 0);
editor.handle.connectNodesByLink(selectedNodeId, 0, link.linkEnd, Number(link.linkEndInputIndex));
if (!isLayer) editor.handle.shiftNode(selectedNodeId);
}
}
@@ -614,7 +614,7 @@
const initialDisconnecting = disconnecting;
if (disconnecting) {
editor.instance.disconnectNodes(BigInt(disconnecting.nodeId), disconnecting.inputIndex);
editor.handle.disconnectNodes(BigInt(disconnecting.nodeId), disconnecting.inputIndex);
}
disconnecting = undefined;
@@ -625,7 +625,7 @@
if (from !== undefined && to !== undefined) {
const { nodeId: outputConnectedNodeID, index: outputNodeConnectionIndex } = from;
const { nodeId: inputConnectedNodeID, index: inputNodeConnectionIndex } = to;
editor.instance.connectNodesByLink(outputConnectedNodeID, outputNodeConnectionIndex, inputConnectedNodeID, inputNodeConnectionIndex);
editor.handle.connectNodesByLink(outputConnectedNodeID, outputNodeConnectionIndex, inputConnectedNodeID, inputNodeConnectionIndex);
}
} else if (linkInProgressFromConnector && !initialDisconnecting) {
// If the add node menu is already open, we don't want to open it again
@@ -645,11 +645,11 @@
} else if (draggingNodes) {
if (draggingNodes.startX === e.x && draggingNodes.startY === e.y) {
if (selectIfNotDragged !== undefined && ($nodeGraph.selected.length !== 1 || $nodeGraph.selected[0] !== selectIfNotDragged)) {
editor.instance.selectNodes(new BigUint64Array([selectIfNotDragged]));
editor.handle.selectNodes(new BigUint64Array([selectIfNotDragged]));
}
}
if ($nodeGraph.selected.length > 0 && (draggingNodes.roundX !== 0 || draggingNodes.roundY !== 0)) editor.instance.moveSelectedNodes(draggingNodes.roundX, draggingNodes.roundY);
if ($nodeGraph.selected.length > 0 && (draggingNodes.roundX !== 0 || draggingNodes.roundY !== 0)) editor.handle.moveSelectedNodes(draggingNodes.roundX, draggingNodes.roundY);
checkInsertBetween();
@@ -670,7 +670,7 @@
const inputNodeConnectionIndex = 0;
const x = Math.round(nodeListLocation.x / GRID_SIZE);
const y = Math.round(nodeListLocation.y / GRID_SIZE) - 1;
const inputConnectedNodeID = editor.instance.createNode(nodeType, x, y);
const inputConnectedNodeID = editor.handle.createNode(nodeType, x, y);
nodeListLocation = undefined;
if (!linkInProgressFromConnector) return;
@@ -678,7 +678,7 @@
if (from !== undefined) {
const { nodeId: outputConnectedNodeID, index: outputNodeConnectionIndex } = from;
editor.instance.connectNodesByLink(outputConnectedNodeID, outputNodeConnectionIndex, inputConnectedNodeID, inputNodeConnectionIndex);
editor.handle.connectNodesByLink(outputConnectedNodeID, outputNodeConnectionIndex, inputConnectedNodeID, inputNodeConnectionIndex);
}
linkInProgressFromConnector = undefined;
@@ -882,7 +882,7 @@
</div>
<div class="details">
<!-- TODO: Allow the user to edit the name, just like in the Layers panel -->
<span title={editor.instance.inDevelopmentMode() ? `Node ID: ${node.id}` : undefined} bind:offsetWidth={layerNameLabelWidths[String(node.id)]}>
<span title={editor.handle.inDevelopmentMode() ? `Node ID: ${node.id}` : undefined} bind:offsetWidth={layerNameLabelWidths[String(node.id)]}>
{node.alias || "Layer"}
</span>
</div>
@@ -929,7 +929,7 @@
<div class="primary" class:no-parameter-section={exposedInputsOutputs.length === 0}>
<IconLabel icon={nodeIcon(node.name)} />
<!-- TODO: Allow the user to edit the name, just like in the Layers panel -->
<TextLabel tooltip={editor.instance.inDevelopmentMode() ? `Node ID: ${node.id}` : undefined}>{node.alias || node.name}</TextLabel>
<TextLabel tooltip={editor.handle.inDevelopmentMode() ? `Node ID: ${node.id}` : undefined}>{node.alias || node.name}</TextLabel>
</div>
<!-- Parameter rows -->
{#if exposedInputsOutputs.length > 0}

View File

@@ -58,15 +58,15 @@
}
function widgetValueCommit(index: number, value: unknown) {
editor.instance.widgetValueCommit(layoutTarget, widgets[index].widgetId, value);
editor.handle.widgetValueCommit(layoutTarget, widgets[index].widgetId, value);
}
function widgetValueUpdate(index: number, value: unknown) {
editor.instance.widgetValueUpdate(layoutTarget, widgets[index].widgetId, value);
editor.handle.widgetValueUpdate(layoutTarget, widgets[index].widgetId, value);
}
function widgetValueCommitAndUpdate(index: number, value: unknown) {
editor.instance.widgetValueCommitAndUpdate(layoutTarget, widgets[index].widgetId, value);
editor.handle.widgetValueCommitAndUpdate(layoutTarget, widgets[index].widgetId, value);
}
// TODO: This seems to work, but verify the correctness and terseness of this, it's adapted from https://stackoverflow.com/a/67434028/775283

View File

@@ -27,11 +27,11 @@
}
function primaryColorChanged(color: Color) {
editor.instance.updatePrimaryColor(color.red, color.green, color.blue, color.alpha);
editor.handle.updatePrimaryColor(color.red, color.green, color.blue, color.alpha);
}
function secondaryColorChanged(color: Color) {
editor.instance.updateSecondaryColor(color.red, color.green, color.blue, color.alpha);
editor.handle.updateSecondaryColor(color.red, color.green, color.blue, color.alpha);
}
</script>

View File

@@ -54,7 +54,7 @@
...entry,
// Shared names with fields that need to be converted from the type used in `MenuBarEntry` to that of `MenuListEntry`
action: () => editor.instance.widgetValueCommitAndUpdate(updateMenuBarLayout.layoutTarget, entry.action.widgetId, undefined),
action: () => editor.handle.widgetValueCommitAndUpdate(updateMenuBarLayout.layoutTarget, entry.action.widgetId, undefined),
children: entry.children ? entry.children.map((entries) => entries.map((entry) => menuBarEntryToMenuListEntry(entry))) : undefined,
// New fields in `MenuListEntry`

View File

@@ -119,7 +119,7 @@
<table>
<tr>
<td>
<TextButton label="New Document" icon="File" flush={true} action={() => editor.instance.newDocumentDialog()} />
<TextButton label="New Document" icon="File" flush={true} action={() => editor.handle.newDocumentDialog()} />
</td>
<td>
<UserInputLabel keysWithLabelsGroups={[[...platformModifiers(true), { key: "KeyN", label: "N" }]]} />
@@ -127,7 +127,7 @@
</tr>
<tr>
<td>
<TextButton label="Open Document" icon="Folder" flush={true} action={() => editor.instance.openDocument()} />
<TextButton label="Open Document" icon="Folder" flush={true} action={() => editor.handle.openDocument()} />
</td>
<td>
<UserInputLabel keysWithLabelsGroups={[[...platformModifiers(false), { key: "KeyO", label: "O" }]]} />
@@ -135,7 +135,7 @@
</tr>
<tr>
<td colspan="2">
<TextButton label="Open Demo Artwork" icon="Image" flush={true} action={() => editor.instance.demoArtworkDialog()} />
<TextButton label="Open Demo Artwork" icon="Image" flush={true} action={() => editor.handle.demoArtworkDialog()} />
</td>
</tr>
</table>

View File

@@ -30,7 +30,7 @@
$: documentTabLabels = $portfolio.documents.map((doc: FrontendDocumentDetails) => {
const name = doc.displayName;
if (!editor.instance.inDevelopmentMode()) return { name };
if (!editor.handle.inDevelopmentMode()) return { name };
const tooltip = `Document ID: ${doc.id}`;
return { name, tooltip };
@@ -105,8 +105,8 @@
tabCloseButtons={true}
tabMinWidths={true}
tabLabels={documentTabLabels}
clickAction={(tabIndex) => editor.instance.selectDocument($portfolio.documents[tabIndex].id)}
closeAction={(tabIndex) => editor.instance.closeDocumentWithConfirmation($portfolio.documents[tabIndex].id)}
clickAction={(tabIndex) => editor.handle.selectDocument($portfolio.documents[tabIndex].id)}
closeAction={(tabIndex) => editor.handle.closeDocumentWithConfirmation($portfolio.documents[tabIndex].id)}
tabActiveIndex={$portfolio.activeDocumentIndex}
bind:this={documentPanel}
/>