mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-18 18:38:05 +08:00
Split apart the frontend Editor type into SubscriptionsRouter and EditorHandle (#3923)
* Remove the unused Editor.raw/wasmMemory/wasmImport * Split out Editor.subscriptions * Replace editor.handle.* with editor.* (1 of 2) * Replace editor.handle.* with editor.* (2 of 2) * Replace Editor typedef with EditorHandle import * Pluralize subscription-router and rename subscriptionsRef->subscriptionsRouter and editorRef->editorHandle * Remove editor.ts * Update the readme * Fix demo art loading bug
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy, setContext } from "svelte";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { EditorHandle } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import { createClipboardManager, destroyClipboardManager } from "@graphite/managers/clipboard";
|
||||
import { createFontsManager, destroyFontsManager } from "@graphite/managers/fonts";
|
||||
import { createHyperlinkManager, destroyHyperlinkManager } from "@graphite/managers/hyperlink";
|
||||
@@ -16,39 +16,42 @@
|
||||
import { createNodeGraphStore, destroyNodeGraphStore } from "@graphite/stores/node-graph";
|
||||
import { createPortfolioStore, destroyPortfolioStore } from "@graphite/stores/portfolio";
|
||||
import { createTooltipStore, destroyTooltipStore } from "@graphite/stores/tooltip";
|
||||
import type { SubscriptionsRouter } from "/src/subscriptions-router";
|
||||
|
||||
import MainWindow from "@graphite/components/window/MainWindow.svelte";
|
||||
|
||||
// Graphite Wasm editor
|
||||
export let editor: Editor;
|
||||
// Graphite Wasm editor and subscriptions router
|
||||
export let subscriptions: SubscriptionsRouter;
|
||||
export let editor: EditorHandle;
|
||||
setContext("subscriptions", subscriptions);
|
||||
setContext("editor", editor);
|
||||
|
||||
const stores = {
|
||||
dialog: createDialogStore(editor),
|
||||
tooltip: createTooltipStore(editor),
|
||||
document: createDocumentStore(editor),
|
||||
fullscreen: createFullscreenStore(editor),
|
||||
nodeGraph: createNodeGraphStore(editor),
|
||||
portfolio: createPortfolioStore(editor),
|
||||
appWindow: createAppWindowStore(editor),
|
||||
dialog: createDialogStore(subscriptions, editor),
|
||||
tooltip: createTooltipStore(subscriptions),
|
||||
document: createDocumentStore(subscriptions),
|
||||
fullscreen: createFullscreenStore(subscriptions),
|
||||
nodeGraph: createNodeGraphStore(subscriptions),
|
||||
portfolio: createPortfolioStore(subscriptions, editor),
|
||||
appWindow: createAppWindowStore(subscriptions),
|
||||
};
|
||||
Object.entries(stores).forEach(([key, store]) => setContext(key, store));
|
||||
|
||||
onMount(() => {
|
||||
createClipboardManager(editor);
|
||||
createHyperlinkManager(editor);
|
||||
createLocalizationManager(editor);
|
||||
createPanicManager(editor);
|
||||
createPersistenceManager(editor, stores.portfolio);
|
||||
createFontsManager(editor);
|
||||
createInputManager(editor, stores.dialog, stores.portfolio, stores.document);
|
||||
createClipboardManager(subscriptions, editor);
|
||||
createHyperlinkManager(subscriptions);
|
||||
createLocalizationManager(subscriptions, editor);
|
||||
createPanicManager(subscriptions);
|
||||
createPersistenceManager(subscriptions, editor, stores.portfolio);
|
||||
createFontsManager(subscriptions, editor);
|
||||
createInputManager(subscriptions, editor, stores.dialog, stores.portfolio, stores.document);
|
||||
|
||||
// Initialize certain setup tasks required by the editor backend to be ready for the user now that the frontend is ready.
|
||||
// The backend handles idempotency, so this is safe to call again during HMR re-mounts.
|
||||
editor.handle.initAfterFrontendReady();
|
||||
editor.initAfterFrontendReady();
|
||||
|
||||
// Re-send all UI layouts from Rust so the frontend has them after an HMR re-mount
|
||||
editor.handle.resendAllLayouts();
|
||||
editor.resendAllLayouts();
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import type { LabeledShortcut } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { EditorHandle, LabeledShortcut } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { TooltipStore } from "@graphite/stores/tooltip";
|
||||
|
||||
import FloatingMenu from "@graphite/components/layout/FloatingMenu.svelte";
|
||||
@@ -11,7 +10,7 @@
|
||||
import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte";
|
||||
|
||||
const tooltip = getContext<TooltipStore>("tooltip");
|
||||
const editor = getContext<Editor>("editor");
|
||||
const editor = getContext<EditorHandle>("editor");
|
||||
|
||||
let self: FloatingMenu | undefined;
|
||||
|
||||
@@ -32,7 +31,7 @@
|
||||
|
||||
// TODO: Once all TODOs are replaced with real text, remove this function
|
||||
function filterTodo(text: string | undefined): string | undefined {
|
||||
if (text?.trim().toUpperCase() === "TODO" && !editor.handle.inDevelopmentMode()) return "";
|
||||
if (text?.trim().toUpperCase() === "TODO" && !editor.inDevelopmentMode()) return "";
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,25 +2,25 @@
|
||||
import { getContext, onMount, onDestroy } from "svelte";
|
||||
|
||||
import type { Layout } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { SubscriptionsRouter } from "/src/subscriptions-router";
|
||||
import { patchLayout } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const subscriptions = getContext<SubscriptionsRouter>("subscriptions");
|
||||
|
||||
let dataPanelLayout: Layout = [];
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("DataPanel", (data) => {
|
||||
subscriptions.subscribeLayoutUpdate("DataPanel", (data) => {
|
||||
patchLayout(dataPanelLayout, data);
|
||||
dataPanelLayout = dataPanelLayout;
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("DataPanel");
|
||||
subscriptions.unsubscribeLayoutUpdate("DataPanel");
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script lang="ts">
|
||||
import { getContext, onMount, onDestroy, tick } from "svelte";
|
||||
|
||||
import type { Color, MenuDirection, MouseCursorIcon } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { Color, EditorHandle, MenuDirection, MouseCursorIcon } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { AppWindowStore } from "@graphite/stores/app-window";
|
||||
import type { DocumentStore } from "@graphite/stores/document";
|
||||
import type { MessageBody } from "@graphite/subscription-router";
|
||||
import type { SubscriptionsRouter } from "/src/subscriptions-router";
|
||||
import type { MessageBody } from "/src/subscriptions-router";
|
||||
import { fillChoiceColor, createColor } from "@graphite/utility-functions/colors";
|
||||
import { pasteFile } from "@graphite/utility-functions/files";
|
||||
import { textInputCleanup } from "@graphite/utility-functions/keyboard-entry";
|
||||
@@ -26,7 +26,8 @@
|
||||
let viewport: HTMLDivElement | undefined;
|
||||
let gradientStopPicker: ColorPicker | undefined;
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const subscriptions = getContext<SubscriptionsRouter>("subscriptions");
|
||||
const editor = getContext<EditorHandle>("editor");
|
||||
const appWindow = getContext<AppWindowStore>("appWindow");
|
||||
const document = getContext<DocumentStore>("document");
|
||||
|
||||
@@ -142,13 +143,13 @@
|
||||
function panCanvasX(newValue: number) {
|
||||
const delta = newValue - scrollbarPos.x;
|
||||
scrollbarPos.x = newValue;
|
||||
editor.handle.panCanvas(-delta * scrollbarMultiplier.x, 0);
|
||||
editor.panCanvas(-delta * scrollbarMultiplier.x, 0);
|
||||
}
|
||||
|
||||
function panCanvasY(newValue: number) {
|
||||
const delta = newValue - scrollbarPos.y;
|
||||
scrollbarPos.y = newValue;
|
||||
editor.handle.panCanvas(0, -delta * scrollbarMultiplier.y);
|
||||
editor.panCanvas(0, -delta * scrollbarMultiplier.y);
|
||||
}
|
||||
|
||||
function canvasPointerDown(e: PointerEvent) {
|
||||
@@ -342,7 +343,7 @@
|
||||
export function triggerTextCommit() {
|
||||
if (!textInput) return;
|
||||
const textCleaned = textInputCleanup(textInput.innerText);
|
||||
editor.handle.onChangeText(textCleaned, false);
|
||||
editor.onChangeText(textCleaned, false);
|
||||
}
|
||||
|
||||
export async function displayEditableTextbox(data: MessageBody<"DisplayEditableTextbox">) {
|
||||
@@ -372,7 +373,7 @@
|
||||
|
||||
textInput.oninput = () => {
|
||||
if (!textInput) return;
|
||||
editor.handle.updateBounds(textInputCleanup(textInput.innerText));
|
||||
editor.updateBounds(textInputCleanup(textInput.innerText));
|
||||
};
|
||||
|
||||
textInputMatrix = data.transform;
|
||||
@@ -454,12 +455,12 @@
|
||||
updatePixelRatio();
|
||||
|
||||
// Update rendered SVGs
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateDocumentArtwork", async (data) => {
|
||||
subscriptions.subscribeFrontendMessage("UpdateDocumentArtwork", async (data) => {
|
||||
await tick();
|
||||
|
||||
updateDocumentArtwork(data.svg);
|
||||
});
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateEyedropperSamplingState", async (data) => {
|
||||
subscriptions.subscribeFrontendMessage("UpdateEyedropperSamplingState", async (data) => {
|
||||
await tick();
|
||||
|
||||
const { image, mousePosition, primaryColor, secondaryColor, setColorChoice } = data;
|
||||
@@ -467,25 +468,25 @@
|
||||
const rgb = await updateEyedropperSamplingState(imageData, mousePosition, primaryColor, secondaryColor);
|
||||
|
||||
if (setColorChoice && rgb) {
|
||||
if (setColorChoice === "Primary") editor.handle.updatePrimaryColor(...rgb, 1);
|
||||
if (setColorChoice === "Secondary") editor.handle.updateSecondaryColor(...rgb, 1);
|
||||
if (setColorChoice === "Primary") editor.updatePrimaryColor(...rgb, 1);
|
||||
if (setColorChoice === "Secondary") editor.updateSecondaryColor(...rgb, 1);
|
||||
}
|
||||
});
|
||||
|
||||
// Gradient stop color picker
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateGradientStopColorPickerPosition", (data) => {
|
||||
subscriptions.subscribeFrontendMessage("UpdateGradientStopColorPickerPosition", (data) => {
|
||||
gradientStopPickerColor = data.color;
|
||||
gradientStopPickerPosition = { x: data.position[0], y: data.position[1] };
|
||||
});
|
||||
|
||||
// Update scrollbars and rulers
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateDocumentScrollbars", async (data) => {
|
||||
subscriptions.subscribeFrontendMessage("UpdateDocumentScrollbars", async (data) => {
|
||||
await tick();
|
||||
|
||||
const { position, size, multiplier } = data;
|
||||
updateDocumentScrollbars(position, size, multiplier);
|
||||
});
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateDocumentRulers", async (data) => {
|
||||
subscriptions.subscribeFrontendMessage("UpdateDocumentRulers", async (data) => {
|
||||
await tick();
|
||||
|
||||
const { origin, spacing, interval, visible } = data;
|
||||
@@ -493,24 +494,24 @@
|
||||
});
|
||||
|
||||
// Update mouse cursor icon
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateMouseCursor", async (data) => {
|
||||
subscriptions.subscribeFrontendMessage("UpdateMouseCursor", async (data) => {
|
||||
await tick();
|
||||
|
||||
updateMouseCursor(data.cursor);
|
||||
});
|
||||
|
||||
// Text entry
|
||||
editor.subscriptions.subscribeFrontendMessage("TriggerTextCommit", async () => {
|
||||
subscriptions.subscribeFrontendMessage("TriggerTextCommit", async () => {
|
||||
await tick();
|
||||
|
||||
triggerTextCommit();
|
||||
});
|
||||
editor.subscriptions.subscribeFrontendMessage("DisplayEditableTextbox", async (data) => {
|
||||
subscriptions.subscribeFrontendMessage("DisplayEditableTextbox", async (data) => {
|
||||
await tick();
|
||||
|
||||
displayEditableTextbox(data);
|
||||
});
|
||||
editor.subscriptions.subscribeFrontendMessage("DisplayEditableTextboxUpdateFontData", async (data) => {
|
||||
subscriptions.subscribeFrontendMessage("DisplayEditableTextboxUpdateFontData", async (data) => {
|
||||
await tick();
|
||||
|
||||
if (textInput && data.fontData.length > 0 && data.fontData.buffer instanceof ArrayBuffer) {
|
||||
@@ -521,10 +522,10 @@
|
||||
textInput.style.fontFamily = "text-font";
|
||||
}
|
||||
});
|
||||
editor.subscriptions.subscribeFrontendMessage("DisplayEditableTextboxTransform", async (data) => {
|
||||
subscriptions.subscribeFrontendMessage("DisplayEditableTextboxTransform", async (data) => {
|
||||
textInputMatrix = data.transform;
|
||||
});
|
||||
editor.subscriptions.subscribeFrontendMessage("DisplayRemoveEditableTextbox", async () => {
|
||||
subscriptions.subscribeFrontendMessage("DisplayRemoveEditableTextbox", async () => {
|
||||
await tick();
|
||||
|
||||
displayRemoveEditableTextbox();
|
||||
@@ -547,17 +548,17 @@
|
||||
removeUpdatePixelRatio?.();
|
||||
addedFontFaces.forEach((face) => window.document.fonts.delete(face));
|
||||
|
||||
editor.subscriptions.unsubscribeFrontendMessage("UpdateDocumentArtwork");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("UpdateEyedropperSamplingState");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("UpdateGradientStopColorPickerPosition");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("UpdateDocumentScrollbars");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("UpdateDocumentRulers");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("UpdateMouseCursor");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("TriggerTextCommit");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("DisplayEditableTextbox");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("DisplayEditableTextboxUpdateFontData");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("DisplayEditableTextboxTransform");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("DisplayRemoveEditableTextbox");
|
||||
subscriptions.unsubscribeFrontendMessage("UpdateDocumentArtwork");
|
||||
subscriptions.unsubscribeFrontendMessage("UpdateEyedropperSamplingState");
|
||||
subscriptions.unsubscribeFrontendMessage("UpdateGradientStopColorPickerPosition");
|
||||
subscriptions.unsubscribeFrontendMessage("UpdateDocumentScrollbars");
|
||||
subscriptions.unsubscribeFrontendMessage("UpdateDocumentRulers");
|
||||
subscriptions.unsubscribeFrontendMessage("UpdateMouseCursor");
|
||||
subscriptions.unsubscribeFrontendMessage("TriggerTextCommit");
|
||||
subscriptions.unsubscribeFrontendMessage("DisplayEditableTextbox");
|
||||
subscriptions.unsubscribeFrontendMessage("DisplayEditableTextboxUpdateFontData");
|
||||
subscriptions.unsubscribeFrontendMessage("DisplayEditableTextboxTransform");
|
||||
subscriptions.unsubscribeFrontendMessage("DisplayRemoveEditableTextbox");
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -628,7 +629,7 @@
|
||||
open={Boolean(gradientStopPickerPosition && gradientStopPickerColor)}
|
||||
on:open={({ detail }) => {
|
||||
if (!detail) {
|
||||
editor.handle.closeGradientStopColorPicker();
|
||||
editor.closeGradientStopColorPicker();
|
||||
gradientStopPickerPosition = undefined;
|
||||
gradientStopPickerColor = undefined;
|
||||
}
|
||||
@@ -636,10 +637,10 @@
|
||||
colorOrGradient={{ Solid: gradientStopPickerColor || createColor(0, 0, 0, 1) }}
|
||||
on:colorOrGradient={({ detail }) => {
|
||||
const color = fillChoiceColor(detail);
|
||||
if (color) editor.handle.updateGradientStopColor(color.red, color.green, color.blue, color.alpha);
|
||||
if (color) editor.updateGradientStopColor(color.red, color.green, color.blue, color.alpha);
|
||||
}}
|
||||
on:startHistoryTransaction={() => editor.handle.startGradientStopColorTransaction()}
|
||||
on:commitHistoryTransaction={() => editor.handle.commitGradientStopColorTransaction()}
|
||||
on:startHistoryTransaction={() => editor.startGradientStopColorTransaction()}
|
||||
on:commitHistoryTransaction={() => editor.commitGradientStopColorTransaction()}
|
||||
bind:this={gradientStopPicker}
|
||||
/>
|
||||
</div>
|
||||
@@ -682,10 +683,10 @@
|
||||
direction="Vertical"
|
||||
thumbLength={scrollbarSize.y}
|
||||
thumbPosition={scrollbarPos.y}
|
||||
on:trackShift={({ detail }) => editor.handle.panCanvasByFraction(0, detail)}
|
||||
on:trackShift={({ detail }) => editor.panCanvasByFraction(0, detail)}
|
||||
on:thumbPosition={({ detail }) => panCanvasY(detail)}
|
||||
on:thumbDragStart={() => editor.handle.panCanvasAbortPrepare(false)}
|
||||
on:thumbDragAbort={() => editor.handle.panCanvasAbort(false)}
|
||||
on:thumbDragStart={() => editor.panCanvasAbortPrepare(false)}
|
||||
on:thumbDragAbort={() => editor.panCanvasAbort(false)}
|
||||
/>
|
||||
</LayoutCol>
|
||||
</LayoutRow>
|
||||
@@ -694,10 +695,10 @@
|
||||
direction="Horizontal"
|
||||
thumbLength={scrollbarSize.x}
|
||||
thumbPosition={scrollbarPos.x}
|
||||
on:trackShift={({ detail }) => editor.handle.panCanvasByFraction(detail, 0)}
|
||||
on:trackShift={({ detail }) => editor.panCanvasByFraction(detail, 0)}
|
||||
on:thumbPosition={({ detail }) => panCanvasX(detail)}
|
||||
on:thumbDragStart={() => editor.handle.panCanvasAbortPrepare(true)}
|
||||
on:thumbDragAbort={() => editor.handle.panCanvasAbort(true)}
|
||||
on:thumbDragStart={() => editor.panCanvasAbortPrepare(true)}
|
||||
on:thumbDragAbort={() => editor.panCanvasAbort(true)}
|
||||
/>
|
||||
</LayoutRow>
|
||||
</LayoutCol>
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
import { getContext, onMount, onDestroy, tick } from "svelte";
|
||||
import { SvelteMap } from "svelte/reactivity";
|
||||
|
||||
import type { LayerPanelEntry, LayerStructureEntry, Layout } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { EditorHandle, LayerPanelEntry, LayerStructureEntry, Layout } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { NodeGraphStore } from "@graphite/stores/node-graph";
|
||||
import type { TooltipStore } from "@graphite/stores/tooltip";
|
||||
import type { SubscriptionsRouter } from "/src/subscriptions-router";
|
||||
import { pasteFile } from "@graphite/utility-functions/files";
|
||||
import { operatingSystem } from "@graphite/utility-functions/platform";
|
||||
import { patchLayout } from "@graphite/utility-functions/widgets";
|
||||
@@ -41,7 +41,8 @@
|
||||
startY: number;
|
||||
};
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const subscriptions = getContext<SubscriptionsRouter>("subscriptions");
|
||||
const editor = getContext<EditorHandle>("editor");
|
||||
const nodeGraph = getContext<NodeGraphStore>("nodeGraph");
|
||||
const tooltip = getContext<TooltipStore>("tooltip");
|
||||
|
||||
@@ -69,26 +70,26 @@
|
||||
let layersPanelBottomBarLayout: Layout = [];
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("LayersPanelControlLeftBar", (data) => {
|
||||
subscriptions.subscribeLayoutUpdate("LayersPanelControlLeftBar", (data) => {
|
||||
patchLayout(layersPanelControlBarLeftLayout, data);
|
||||
layersPanelControlBarLeftLayout = layersPanelControlBarLeftLayout;
|
||||
});
|
||||
|
||||
editor.subscriptions.subscribeLayoutUpdate("LayersPanelControlRightBar", (data) => {
|
||||
subscriptions.subscribeLayoutUpdate("LayersPanelControlRightBar", (data) => {
|
||||
patchLayout(layersPanelControlBarRightLayout, data);
|
||||
layersPanelControlBarRightLayout = layersPanelControlBarRightLayout;
|
||||
});
|
||||
|
||||
editor.subscriptions.subscribeLayoutUpdate("LayersPanelBottomBar", (data) => {
|
||||
subscriptions.subscribeLayoutUpdate("LayersPanelBottomBar", (data) => {
|
||||
patchLayout(layersPanelBottomBarLayout, data);
|
||||
layersPanelBottomBarLayout = layersPanelBottomBarLayout;
|
||||
});
|
||||
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateDocumentLayerStructure", (data) => {
|
||||
subscriptions.subscribeFrontendMessage("UpdateDocumentLayerStructure", (data) => {
|
||||
rebuildLayerHierarchy(data.layerStructure);
|
||||
});
|
||||
|
||||
editor.subscriptions.subscribeFrontendMessage("UpdateDocumentLayerDetails", (data) => {
|
||||
subscriptions.subscribeFrontendMessage("UpdateDocumentLayerDetails", (data) => {
|
||||
const targetLayer = data.data;
|
||||
const targetId = targetLayer.id;
|
||||
|
||||
@@ -107,11 +108,11 @@
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("LayersPanelControlLeftBar");
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("LayersPanelControlRightBar");
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("LayersPanelBottomBar");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("UpdateDocumentLayerStructure");
|
||||
editor.subscriptions.unsubscribeFrontendMessage("UpdateDocumentLayerDetails");
|
||||
subscriptions.unsubscribeLayoutUpdate("LayersPanelControlLeftBar");
|
||||
subscriptions.unsubscribeLayoutUpdate("LayersPanelControlRightBar");
|
||||
subscriptions.unsubscribeLayoutUpdate("LayersPanelBottomBar");
|
||||
subscriptions.unsubscribeFrontendMessage("UpdateDocumentLayerStructure");
|
||||
subscriptions.unsubscribeFrontendMessage("UpdateDocumentLayerDetails");
|
||||
|
||||
removeEventListener("pointerup", draggingPointerUp);
|
||||
removeEventListener("pointermove", draggingPointerMove);
|
||||
@@ -125,17 +126,17 @@
|
||||
});
|
||||
|
||||
function toggleNodeVisibilityLayerPanel(id: bigint) {
|
||||
editor.handle.toggleNodeVisibilityLayerPanel(id);
|
||||
editor.toggleNodeVisibilityLayerPanel(id);
|
||||
}
|
||||
|
||||
function toggleLayerLock(id: bigint) {
|
||||
editor.handle.toggleLayerLock(id);
|
||||
editor.toggleLayerLock(id);
|
||||
}
|
||||
|
||||
function handleExpandArrowClickWithModifiers(e: MouseEvent, id: bigint) {
|
||||
const accel = operatingSystem() === "Mac" ? e.metaKey : e.ctrlKey;
|
||||
const collapseRecursive = e.altKey || accel;
|
||||
editor.handle.toggleLayerExpansion(id, collapseRecursive);
|
||||
editor.toggleLayerExpansion(id, collapseRecursive);
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
@@ -162,7 +163,7 @@
|
||||
layers = layers;
|
||||
|
||||
const name = (e.target instanceof HTMLInputElement && e.target.value) || "";
|
||||
editor.handle.setLayerName(listing.entry.id, name);
|
||||
editor.setLayerName(listing.entry.id, name);
|
||||
listing.entry.alias = name;
|
||||
}
|
||||
|
||||
@@ -200,7 +201,7 @@
|
||||
}
|
||||
|
||||
function clipLayer(listing: LayerListingInfo) {
|
||||
editor.handle.clipLayer(listing.entry.id);
|
||||
editor.clipLayer(listing.entry.id);
|
||||
}
|
||||
|
||||
function clippingKeyPress(e: KeyboardEvent) {
|
||||
@@ -247,7 +248,7 @@
|
||||
// Don't select while we are entering text to rename the layer
|
||||
if (listing.editingName) return;
|
||||
|
||||
editor.handle.selectLayer(listing.entry.id, accel, shift);
|
||||
editor.selectLayer(listing.entry.id, accel, shift);
|
||||
}
|
||||
|
||||
async function deselectAllLayers() {
|
||||
@@ -256,7 +257,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
editor.handle.deselectAllLayers();
|
||||
editor.deselectAllLayers();
|
||||
}
|
||||
|
||||
function calculateDragIndex(tree: LayoutCol, clientY: number, select?: () => void): DraggingData {
|
||||
@@ -389,7 +390,7 @@
|
||||
|
||||
// Commit the move
|
||||
select?.();
|
||||
editor.handle.moveLayerInTree(insertParentId, insertIndex);
|
||||
editor.moveLayerInTree(insertParentId, insertIndex);
|
||||
|
||||
// Prevent the subsequent click event from processing
|
||||
justFinishedDrag = true;
|
||||
@@ -445,7 +446,7 @@
|
||||
const inputElement = document.activeElement;
|
||||
if (inputElement instanceof HTMLInputElement) {
|
||||
const name = inputElement.value || "";
|
||||
editor.handle.setLayerName(currentListing.entry.id, name);
|
||||
editor.setLayerName(currentListing.entry.id, name);
|
||||
currentListing.entry.alias = name;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,25 +2,25 @@
|
||||
import { getContext, onMount, onDestroy } from "svelte";
|
||||
|
||||
import type { Layout } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { SubscriptionsRouter } from "/src/subscriptions-router";
|
||||
import { patchLayout } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const subscriptions = getContext<SubscriptionsRouter>("subscriptions");
|
||||
|
||||
let propertiesPanelLayout: Layout = [];
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("PropertiesPanel", (data) => {
|
||||
subscriptions.subscribeLayoutUpdate("PropertiesPanel", (data) => {
|
||||
patchLayout(propertiesPanelLayout, data);
|
||||
propertiesPanelLayout = propertiesPanelLayout;
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("PropertiesPanel");
|
||||
subscriptions.unsubscribeLayoutUpdate("PropertiesPanel");
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
import { getContext, onMount, onDestroy } from "svelte";
|
||||
|
||||
import { isPlatformNative } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Layout } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { EditorHandle, Layout } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { SubscriptionsRouter } from "/src/subscriptions-router";
|
||||
import { pasteFile } from "@graphite/utility-functions/files";
|
||||
import { patchLayout } from "@graphite/utility-functions/widgets";
|
||||
|
||||
@@ -13,19 +13,20 @@
|
||||
import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte";
|
||||
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const subscriptions = getContext<SubscriptionsRouter>("subscriptions");
|
||||
const editor = getContext<EditorHandle>("editor");
|
||||
|
||||
let welcomePanelButtonsLayout: Layout = [];
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("WelcomeScreenButtons", (data) => {
|
||||
subscriptions.subscribeLayoutUpdate("WelcomeScreenButtons", (data) => {
|
||||
patchLayout(welcomePanelButtonsLayout, data);
|
||||
welcomePanelButtonsLayout = welcomePanelButtonsLayout;
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("WelcomeScreenButtons");
|
||||
subscriptions.unsubscribeLayoutUpdate("WelcomeScreenButtons");
|
||||
});
|
||||
|
||||
function dropFile(e: DragEvent) {
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
import { cubicInOut } from "svelte/easing";
|
||||
import { fade } from "svelte/transition";
|
||||
|
||||
import type { FrontendGraphInput, FrontendGraphOutput, FrontendNode } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { EditorHandle, FrontendGraphInput, FrontendGraphOutput, FrontendNode } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { DocumentStore } from "@graphite/stores/document";
|
||||
import { closeContextMenu } from "@graphite/stores/node-graph";
|
||||
import type { NodeGraphStore } from "@graphite/stores/node-graph";
|
||||
@@ -20,7 +19,7 @@
|
||||
const GRID_SIZE = 24;
|
||||
const FADE_TRANSITION = { duration: 200, easing: cubicInOut };
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const editor = getContext<EditorHandle>("editor");
|
||||
const nodeGraph = getContext<NodeGraphStore>("nodeGraph");
|
||||
const documentState = getContext<DocumentStore>("document");
|
||||
|
||||
@@ -83,7 +82,7 @@
|
||||
if (editingNameImportIndex !== undefined) {
|
||||
if (!(event.target instanceof HTMLInputElement)) return;
|
||||
let text = event.target.value;
|
||||
editor.handle.setImportName(editingNameImportIndex, text);
|
||||
editor.setImportName(editingNameImportIndex, text);
|
||||
editingNameImportIndex = undefined;
|
||||
}
|
||||
}
|
||||
@@ -92,7 +91,7 @@
|
||||
if (editingNameExportIndex !== undefined) {
|
||||
if (!(event.target instanceof HTMLInputElement)) return;
|
||||
let text = event.target.value;
|
||||
editor.handle.setExportName(editingNameExportIndex, text);
|
||||
editor.setExportName(editingNameExportIndex, text);
|
||||
editingNameExportIndex = undefined;
|
||||
}
|
||||
}
|
||||
@@ -111,7 +110,7 @@
|
||||
function createNode(identifier: string) {
|
||||
if ($nodeGraph.contextMenuInformation === undefined) return;
|
||||
|
||||
editor.handle.createNode(identifier, $nodeGraph.contextMenuInformation.contextMenuCoordinates[0], $nodeGraph.contextMenuInformation.contextMenuCoordinates[1]);
|
||||
editor.createNode(identifier, $nodeGraph.contextMenuInformation.contextMenuCoordinates[0], $nodeGraph.contextMenuInformation.contextMenuCoordinates[1]);
|
||||
}
|
||||
|
||||
function nodeBorderMask(nodeWidth: number, primaryInputExists: boolean, exposedSecondaryInputs: number, primaryOutputExists: boolean, exposedSecondaryOutputs: number): string {
|
||||
@@ -174,11 +173,11 @@
|
||||
}
|
||||
|
||||
function outputConnectedToText(output: FrontendGraphOutput): string {
|
||||
return editor.handle.inDevelopmentMode() ? output.connectedTo.join("\n") : "";
|
||||
return editor.inDevelopmentMode() ? output.connectedTo.join("\n") : "";
|
||||
}
|
||||
|
||||
function inputConnectedToText(input: FrontendGraphInput): string {
|
||||
return editor.handle.inDevelopmentMode() ? input.connectedTo : "";
|
||||
return editor.inDevelopmentMode() ? input.connectedTo : "";
|
||||
}
|
||||
|
||||
function zipWithUndefined(arr1: FrontendGraphInput[], arr2: FrontendGraphOutput[]) {
|
||||
@@ -220,7 +219,7 @@
|
||||
<TextButton
|
||||
label="Merge Selected Nodes"
|
||||
action={() => {
|
||||
editor.handle.mergeSelectedNodes();
|
||||
editor.mergeSelectedNodes();
|
||||
closeContextMenu();
|
||||
}}
|
||||
flush={true}
|
||||
@@ -230,7 +229,7 @@
|
||||
label={currentlyIsNode ? "Display as Layer" : "Display as Node"}
|
||||
action={() => {
|
||||
if ($nodeGraph.contextMenuInformation?.contextMenuData.type === "ModifyNode") {
|
||||
editor.handle.setToNodeOrLayer($nodeGraph.contextMenuInformation.contextMenuData.data.nodeId, currentlyIsNode);
|
||||
editor.setToNodeOrLayer($nodeGraph.contextMenuInformation.contextMenuData.data.nodeId, currentlyIsNode);
|
||||
}
|
||||
closeContextMenu();
|
||||
}}
|
||||
@@ -244,9 +243,9 @@
|
||||
label={allLocked ? "Unlock" : "Lock"}
|
||||
action={() => {
|
||||
if ($nodeGraph.selected.includes(nodeId)) {
|
||||
editor.handle.toggleSelectedLocked();
|
||||
editor.toggleSelectedLocked();
|
||||
} else {
|
||||
editor.handle.toggleLayerLock(nodeId);
|
||||
editor.toggleLayerLock(nodeId);
|
||||
}
|
||||
closeContextMenu();
|
||||
}}
|
||||
@@ -383,7 +382,7 @@
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.importPosition[1] - 12) / 24}
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.importPosition[0] - 12) / 24}
|
||||
>
|
||||
<IconButton size={24} icon="Add" action={() => editor.handle.addPrimaryImport()} />
|
||||
<IconButton size={24} icon="Add" action={() => editor.addPrimaryImport()} />
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
@@ -454,7 +453,7 @@
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.exportPosition[0] - 12) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.exportPosition[1] - 12) / 24}
|
||||
>
|
||||
<IconButton size={24} icon="Add" action={() => editor.handle.addPrimaryExport()} />
|
||||
<IconButton size={24} icon="Add" action={() => editor.addPrimaryExport()} />
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
@@ -465,14 +464,14 @@
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.importPosition[0] - 12) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.importPosition[1] - 12) / 24 + $nodeGraph.updateImportsExports.imports.length}
|
||||
>
|
||||
<IconButton size={24} icon="Add" action={() => editor.handle.addSecondaryImport()} />
|
||||
<IconButton size={24} icon="Add" action={() => editor.addSecondaryImport()} />
|
||||
</div>
|
||||
<div
|
||||
class="plus"
|
||||
style:--offset-left={($nodeGraph.updateImportsExports.exportPosition[0] - 12) / 24}
|
||||
style:--offset-top={($nodeGraph.updateImportsExports.exportPosition[1] - 12) / 24 + $nodeGraph.updateImportsExports.exports.length}
|
||||
>
|
||||
<IconButton size={24} icon="Add" action={() => editor.handle.addSecondaryExport()} />
|
||||
<IconButton size={24} icon="Add" action={() => editor.addSecondaryExport()} />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -522,7 +521,7 @@
|
||||
style:--node-chain-area-left-extension={layerChainWidth !== 0 ? layerChainWidth + 0.5 : 0}
|
||||
data-tooltip-label={nodeNameTooltipLabel(node)}
|
||||
data-tooltip-description={`
|
||||
${(description || "").trim()}${editor.handle.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position[0]}, ${node.position[1]}).` : ""}
|
||||
${(description || "").trim()}${editor.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position[0]}, ${node.position[1]}).` : ""}
|
||||
`.trim()}
|
||||
data-node={node.id}
|
||||
>
|
||||
@@ -685,7 +684,7 @@
|
||||
style:--data-color-dim={`var(--color-data-${(node.primaryOutput?.dataType || "General").toLowerCase()}-dim)`}
|
||||
data-tooltip-label={nodeNameTooltipLabel(node)}
|
||||
data-tooltip-description={`
|
||||
${(description || "").trim()}${editor.handle.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position[0]}, ${node.position[1]}).` : ""}
|
||||
${(description || "").trim()}${editor.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position[0]}, ${node.position[1]}).` : ""}
|
||||
`.trim()}
|
||||
data-node={node.id}
|
||||
>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import type { LayoutTarget, WidgetSection as WidgetSectionData } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { EditorHandle, LayoutTarget, WidgetSection as WidgetSectionData } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
import IconButton from "@graphite/components/widgets/buttons/IconButton.svelte";
|
||||
@@ -18,7 +17,7 @@
|
||||
|
||||
let expanded = true;
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const editor = getContext<EditorHandle>("editor");
|
||||
</script>
|
||||
|
||||
<!-- TODO: Implement collapsable sections with properties system -->
|
||||
@@ -31,7 +30,7 @@
|
||||
tooltipDescription={widgetData.pinned ? "Unpin this node so it's no longer shown here when nothing is selected." : "Pin this node so it's shown here when nothing is selected."}
|
||||
size={24}
|
||||
action={(e) => {
|
||||
editor.handle.setNodePinned(widgetData.id, !widgetData.pinned);
|
||||
editor.setNodePinned(widgetData.id, !widgetData.pinned);
|
||||
e?.stopPropagation();
|
||||
}}
|
||||
class="show-only-on-hover"
|
||||
@@ -41,7 +40,7 @@
|
||||
tooltipDescription="Delete this node from the layer chain."
|
||||
size={24}
|
||||
action={(e) => {
|
||||
editor.handle.deleteNode(widgetData.id);
|
||||
editor.deleteNode(widgetData.id);
|
||||
e?.stopPropagation();
|
||||
}}
|
||||
class="show-only-on-hover"
|
||||
@@ -52,7 +51,7 @@
|
||||
tooltipDescription={widgetData.visible ? "Hide this node." : "Show this node."}
|
||||
size={24}
|
||||
action={(e) => {
|
||||
editor.handle.toggleNodeVisibilityLayerPanel(widgetData.id);
|
||||
editor.toggleNodeVisibilityLayerPanel(widgetData.id);
|
||||
e?.stopPropagation();
|
||||
}}
|
||||
class={widgetData.visible ? "show-only-on-hover" : ""}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import type { LayoutTarget, Widget, WidgetInstance } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { EditorHandle, LayoutTarget, Widget, WidgetInstance } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import { parseFillChoice } from "@graphite/utility-functions/colors";
|
||||
|
||||
import NodeCatalog from "@graphite/components/floating-menus/NodeCatalog.svelte";
|
||||
@@ -35,7 +34,7 @@
|
||||
// A Widget tagged enum unwrapped into a correlated [kind, props] tuple
|
||||
type UnwrappedWidget = { [K in WidgetKind]: [kind: K, props: WidgetProps<K>] }[WidgetKind];
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const editor = getContext<EditorHandle>("editor");
|
||||
|
||||
export let widgets: WidgetInstance[];
|
||||
export let direction: "row" | "column";
|
||||
@@ -52,15 +51,15 @@
|
||||
.join(" ");
|
||||
|
||||
function widgetValueCommit(widgetIndex: number, value: unknown) {
|
||||
editor.handle.widgetValueCommit(layoutTarget, widgets[widgetIndex].widgetId, value);
|
||||
editor.widgetValueCommit(layoutTarget, widgets[widgetIndex].widgetId, value);
|
||||
}
|
||||
|
||||
function widgetValueUpdate(widgetIndex: number, value: unknown, resendWidget: boolean) {
|
||||
editor.handle.widgetValueUpdate(layoutTarget, widgets[widgetIndex].widgetId, value, resendWidget);
|
||||
editor.widgetValueUpdate(layoutTarget, widgets[widgetIndex].widgetId, value, resendWidget);
|
||||
}
|
||||
|
||||
function widgetValueCommitAndUpdate(widgetIndex: number, value: unknown, resendWidget: boolean) {
|
||||
editor.handle.widgetValueCommitAndUpdate(layoutTarget, widgets[widgetIndex].widgetId, value, resendWidget);
|
||||
editor.widgetValueCommitAndUpdate(layoutTarget, widgets[widgetIndex].widgetId, value, resendWidget);
|
||||
}
|
||||
|
||||
// Extracts the kind and props from a Widget tagged enum, validated against the widget registry.
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
import { createEventDispatcher, onMount, onDestroy, getContext } from "svelte";
|
||||
|
||||
import { evaluateMathExpression, isPlatformNative } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { NumberInputMode, NumberInputIncrementBehavior, ActionShortcut } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { ActionShortcut, EditorHandle, NumberInputIncrementBehavior, NumberInputMode } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import { PRESS_REPEAT_DELAY_MS, PRESS_REPEAT_INTERVAL_MS } from "@graphite/managers/input";
|
||||
import { browserVersion } from "@graphite/utility-functions/platform";
|
||||
|
||||
@@ -17,7 +16,7 @@
|
||||
|
||||
const dispatch = createEventDispatcher<{ value: number | undefined; startHistoryTransaction: undefined }>();
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const editor = getContext<EditorHandle>("editor");
|
||||
|
||||
// Content
|
||||
/// When `value` is not provided (i.e. it's `undefined`), a dash is displayed.
|
||||
@@ -408,7 +407,7 @@
|
||||
// Enter dragging state
|
||||
if (usePointerLock) target.requestPointerLock();
|
||||
if (isPlatformNative()) {
|
||||
editor.handle.appWindowPointerLock();
|
||||
editor.appWindowPointerLock();
|
||||
}
|
||||
initialValueBeforeDragging = value;
|
||||
cumulativeDragDelta = 0;
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import type { Color } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { Color, EditorHandle } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import { fillChoiceColor, colorToRgbaCSS } from "@graphite/utility-functions/colors";
|
||||
|
||||
import ColorPicker from "@graphite/components/floating-menus/ColorPicker.svelte";
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const editor = getContext<EditorHandle>("editor");
|
||||
|
||||
// Content
|
||||
export let primary: Color;
|
||||
@@ -29,11 +28,11 @@
|
||||
}
|
||||
|
||||
function primaryColorChanged(color: Color) {
|
||||
editor.handle.updatePrimaryColor(color.red, color.green, color.blue, color.alpha);
|
||||
editor.updatePrimaryColor(color.red, color.green, color.blue, color.alpha);
|
||||
}
|
||||
|
||||
function secondaryColorChanged(color: Color) {
|
||||
editor.handle.updateSecondaryColor(color.red, color.green, color.blue, color.alpha);
|
||||
editor.updateSecondaryColor(color.red, color.green, color.blue, color.alpha);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { getContext, tick } from "svelte";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { EditorHandle } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
@@ -25,7 +25,7 @@
|
||||
const BUTTON_LEFT = 0;
|
||||
const BUTTON_MIDDLE = 1;
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const editor = getContext<EditorHandle>("editor");
|
||||
|
||||
export let tabMinWidths = false;
|
||||
export let tabCloseButtons = false;
|
||||
@@ -56,7 +56,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<LayoutCol on:pointerdown={() => panelType && editor.handle.setActivePanel(panelType)} class={`panel ${className}`.trim()} {classes} style={styleName} {styles}>
|
||||
<LayoutCol on:pointerdown={() => panelType && editor.setActivePanel(panelType)} class={`panel ${className}`.trim()} {classes} style={styleName} {styles}>
|
||||
<LayoutRow class="tab-bar" classes={{ "min-widths": tabMinWidths }}>
|
||||
<LayoutRow class="tab-group" scrollableX={true} on:click={onEmptySpaceAction} on:auxclick={onEmptySpaceAction}>
|
||||
{#each tabLabels as tabLabel, tabIndex}
|
||||
|
||||
@@ -2,32 +2,33 @@
|
||||
import { getContext, onMount, onDestroy } from "svelte";
|
||||
|
||||
import type { Layout } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { SubscriptionsRouter } from "/src/subscriptions-router";
|
||||
import { patchLayout } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
import Separator from "@graphite/components/widgets/labels/Separator.svelte";
|
||||
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const subscriptions = getContext<SubscriptionsRouter>("subscriptions");
|
||||
|
||||
let statusBarHintsLayout: Layout = [];
|
||||
let statusBarInfoLayout: Layout = [];
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("StatusBarHints", (data) => {
|
||||
subscriptions.subscribeLayoutUpdate("StatusBarHints", (data) => {
|
||||
patchLayout(statusBarHintsLayout, data);
|
||||
statusBarHintsLayout = statusBarHintsLayout;
|
||||
});
|
||||
editor.subscriptions.subscribeLayoutUpdate("StatusBarInfo", (data) => {
|
||||
|
||||
subscriptions.subscribeLayoutUpdate("StatusBarInfo", (data) => {
|
||||
patchLayout(statusBarInfoLayout, data);
|
||||
statusBarInfoLayout = statusBarInfoLayout;
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("StatusBarHints");
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("StatusBarInfo");
|
||||
subscriptions.unsubscribeLayoutUpdate("StatusBarHints");
|
||||
subscriptions.unsubscribeLayoutUpdate("StatusBarInfo");
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
import { getContext, onMount, onDestroy } from "svelte";
|
||||
|
||||
import { isPlatformNative } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Layout } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { EditorHandle, Layout } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { AppWindowStore } from "@graphite/stores/app-window";
|
||||
import { enterFullscreen, exitFullscreen } from "@graphite/stores/fullscreen";
|
||||
import type { FullscreenStore } from "@graphite/stores/fullscreen";
|
||||
import type { TooltipStore } from "@graphite/stores/tooltip";
|
||||
import type { SubscriptionsRouter } from "/src/subscriptions-router";
|
||||
import { patchLayout } from "@graphite/utility-functions/widgets";
|
||||
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
@@ -16,8 +16,9 @@
|
||||
|
||||
const keyboardLockApiSupported = navigator.keyboard !== undefined && "lock" in navigator.keyboard;
|
||||
|
||||
const editor = getContext<EditorHandle>("editor");
|
||||
const subscriptions = getContext<SubscriptionsRouter>("subscriptions");
|
||||
const appWindow = getContext<AppWindowStore>("appWindow");
|
||||
const editor = getContext<Editor>("editor");
|
||||
const fullscreen = getContext<FullscreenStore>("fullscreen");
|
||||
const tooltip = getContext<TooltipStore>("tooltip");
|
||||
|
||||
@@ -29,14 +30,14 @@
|
||||
$: height = $appWindow.platform === "Mac" ? 28 * (1 / $appWindow.uiScale) : 28;
|
||||
|
||||
onMount(() => {
|
||||
editor.subscriptions.subscribeLayoutUpdate("MenuBar", (data) => {
|
||||
subscriptions.subscribeLayoutUpdate("MenuBar", (data) => {
|
||||
patchLayout(menuBarLayout, data);
|
||||
menuBarLayout = menuBarLayout;
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
editor.subscriptions.unsubscribeLayoutUpdate("MenuBar");
|
||||
subscriptions.unsubscribeLayoutUpdate("MenuBar");
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -48,7 +49,7 @@
|
||||
{/if}
|
||||
</LayoutRow>
|
||||
<!-- Window frame -->
|
||||
<LayoutRow class="window-frame" on:mousedown={() => !isFullscreen && editor.handle.appWindowDrag()} on:dblclick={() => !isFullscreen && editor.handle.appWindowMaximize()} />
|
||||
<LayoutRow class="window-frame" on:mousedown={() => !isFullscreen && editor.appWindowDrag()} on:dblclick={() => !isFullscreen && editor.appWindowMaximize()} />
|
||||
<!-- Window buttons -->
|
||||
<LayoutRow class="window-buttons" classes={{ fullscreen: showFullscreenButton, windows: $appWindow.platform === "Windows", linux: $appWindow.platform === "Linux" }}>
|
||||
{#if $appWindow.platform !== "Mac"}
|
||||
@@ -60,20 +61,20 @@
|
||||
: undefined}
|
||||
tooltipShortcut={$tooltip.fullscreenShortcut}
|
||||
on:click={() => {
|
||||
if (isPlatformNative()) editor.handle.appWindowFullscreen();
|
||||
if (isPlatformNative()) editor.appWindowFullscreen();
|
||||
else ($fullscreen.windowFullscreen ? exitFullscreen : enterFullscreen)();
|
||||
}}
|
||||
>
|
||||
<IconLabel icon={isFullscreen ? "FullscreenExit" : "FullscreenEnter"} />
|
||||
</LayoutRow>
|
||||
{:else}
|
||||
<LayoutRow tooltipLabel="Minimize" on:click={() => editor.handle.appWindowMinimize()}>
|
||||
<LayoutRow tooltipLabel="Minimize" on:click={() => editor.appWindowMinimize()}>
|
||||
<IconLabel icon="WindowButtonWinMinimize" />
|
||||
</LayoutRow>
|
||||
<LayoutRow tooltipLabel={$appWindow.maximized ? ($appWindow.platform === "Windows" ? "Restore Down" : "Unmaximize") : "Maximize"} on:click={() => editor.handle.appWindowMaximize()}>
|
||||
<LayoutRow tooltipLabel={$appWindow.maximized ? ($appWindow.platform === "Windows" ? "Restore Down" : "Unmaximize") : "Maximize"} on:click={() => editor.appWindowMaximize()}>
|
||||
<IconLabel icon={$appWindow.maximized ? "WindowButtonWinRestoreDown" : "WindowButtonWinMaximize"} />
|
||||
</LayoutRow>
|
||||
<LayoutRow tooltipLabel="Close" on:click={() => editor.handle.appWindowClose()}>
|
||||
<LayoutRow tooltipLabel="Close" on:click={() => editor.appWindowClose()}>
|
||||
<IconLabel icon="WindowButtonWinClose" />
|
||||
</LayoutRow>
|
||||
{/if}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { getContext, onDestroy } from "svelte";
|
||||
|
||||
import type { OpenDocument } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { EditorHandle, OpenDocument } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||
import type { PortfolioStore } from "@graphite/stores/portfolio";
|
||||
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
@@ -35,13 +34,13 @@
|
||||
$: documentTabLabels = $portfolio.documents.map((doc: OpenDocument) => {
|
||||
const name = doc.details.name;
|
||||
const unsaved = !doc.details.isSaved;
|
||||
if (!editor.handle.inDevelopmentMode()) return { name, unsaved };
|
||||
if (!editor.inDevelopmentMode()) return { name, unsaved };
|
||||
|
||||
const tooltipDescription = `Document ID: ${doc.id}`;
|
||||
return { name, unsaved, tooltipLabel: name, tooltipDescription };
|
||||
});
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const editor = getContext<EditorHandle>("editor");
|
||||
const portfolio = getContext<PortfolioStore>("portfolio");
|
||||
|
||||
function resizePanel(e: PointerEvent) {
|
||||
@@ -151,9 +150,9 @@
|
||||
tabCloseButtons={true}
|
||||
tabMinWidths={true}
|
||||
tabLabels={documentTabLabels}
|
||||
emptySpaceAction={() => editor.handle.newDocumentDialog()}
|
||||
clickAction={(tabIndex) => editor.handle.selectDocument($portfolio.documents[tabIndex].id)}
|
||||
closeAction={(tabIndex) => editor.handle.closeDocumentWithConfirmation($portfolio.documents[tabIndex].id)}
|
||||
emptySpaceAction={() => editor.newDocumentDialog()}
|
||||
clickAction={(tabIndex) => editor.selectDocument($portfolio.documents[tabIndex].id)}
|
||||
closeAction={(tabIndex) => editor.closeDocumentWithConfirmation($portfolio.documents[tabIndex].id)}
|
||||
tabActiveIndex={$portfolio.activeDocumentIndex}
|
||||
bind:this={documentPanel}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user