Fix node colors; fix spacebar not closing graph

This commit is contained in:
Keavon Chambers 2023-08-20 23:32:27 -07:00
parent 8fbf0cbb69
commit 0e97a256b7
6 changed files with 40 additions and 62 deletions

View File

@ -16,7 +16,6 @@
import { createFullscreenState } from "@graphite/state-providers/fullscreen"; import { createFullscreenState } from "@graphite/state-providers/fullscreen";
import { createNodeGraphState } from "@graphite/state-providers/node-graph"; import { createNodeGraphState } from "@graphite/state-providers/node-graph";
import { createPortfolioState } from "@graphite/state-providers/portfolio"; import { createPortfolioState } from "@graphite/state-providers/portfolio";
import { createWorkspaceState } from "@graphite/state-providers/workspace";
import MainWindow from "@graphite/components/window/MainWindow.svelte"; import MainWindow from "@graphite/components/window/MainWindow.svelte";
@ -37,8 +36,6 @@
setContext("nodeGraph", nodeGraph); setContext("nodeGraph", nodeGraph);
let portfolio = createPortfolioState(editor); let portfolio = createPortfolioState(editor);
setContext("portfolio", portfolio); setContext("portfolio", portfolio);
let workspace = createWorkspaceState(editor);
setContext("workspace", workspace);
// Initialize managers, which are isolated systems that subscribe to backend messages to link them to browser API functionality (like JS events, IndexedDB, etc.) // Initialize managers, which are isolated systems that subscribe to backend messages to link them to browser API functionality (like JS events, IndexedDB, etc.)
createClipboardManager(editor); createClipboardManager(editor);

View File

@ -35,7 +35,7 @@
let rulerHorizontal: CanvasRuler | undefined; let rulerHorizontal: CanvasRuler | undefined;
let rulerVertical: CanvasRuler | undefined; let rulerVertical: CanvasRuler | undefined;
let canvasContainer: HTMLDivElement | undefined; let viewport: HTMLDivElement | undefined;
const editor = getContext<Editor>("editor"); const editor = getContext<Editor>("editor");
const document = getContext<DocumentState>("document"); const document = getContext<DocumentState>("document");
@ -126,7 +126,7 @@
function canvasPointerDown(e: PointerEvent) { function canvasPointerDown(e: PointerEvent) {
const onEditbox = e.target instanceof HTMLDivElement && e.target.contentEditable; const onEditbox = e.target instanceof HTMLDivElement && e.target.contentEditable;
if (!onEditbox) canvasContainer?.setPointerCapture(e.pointerId); if (!onEditbox) viewport?.setPointerCapture(e.pointerId);
} }
// Update rendered SVGs // Update rendered SVGs
@ -136,7 +136,7 @@
await tick(); await tick();
const placeholders = window.document.querySelectorAll("[data-canvas] [data-canvas-placeholder]"); const placeholders = window.document.querySelectorAll("[data-viewport] [data-canvas-placeholder]");
// Replace the placeholders with the actual canvas elements // Replace the placeholders with the actual canvas elements
placeholders.forEach((placeholder) => { placeholders.forEach((placeholder) => {
const canvasName = placeholder.getAttribute("data-canvas-placeholder"); const canvasName = placeholder.getAttribute("data-canvas-placeholder");
@ -317,11 +317,11 @@
// Resize elements to render the new viewport size // Resize elements to render the new viewport size
export function viewportResize() { export function viewportResize() {
if (!canvasContainer) return; if (!viewport) return;
// Resize the canvas // Resize the canvas
canvasSvgWidth = Math.ceil(parseFloat(getComputedStyle(canvasContainer).width)); canvasSvgWidth = Math.ceil(parseFloat(getComputedStyle(viewport).width));
canvasSvgHeight = Math.ceil(parseFloat(getComputedStyle(canvasContainer).height)); canvasSvgHeight = Math.ceil(parseFloat(getComputedStyle(viewport).height));
// Resize the rulers // Resize the rulers
rulerHorizontal?.resize(); rulerHorizontal?.resize();
@ -440,38 +440,34 @@
{#if !graphViewOverlayOpen} {#if !graphViewOverlayOpen}
<WidgetLayout layout={$document.documentModeLayout} /> <WidgetLayout layout={$document.documentModeLayout} />
<WidgetLayout layout={$document.toolOptionsLayout} /> <WidgetLayout layout={$document.toolOptionsLayout} />
<LayoutRow class="spacer" /> <LayoutRow class="spacer" />
<WidgetLayout layout={$document.documentBarLayout} /> <WidgetLayout layout={$document.documentBarLayout} />
{:else} {:else}
<WidgetLayout layout={$document.nodeGraphBarLayout} /> <WidgetLayout layout={$document.nodeGraphBarLayout} />
{/if} {/if}
</LayoutRow> </LayoutRow>
<LayoutRow class="shelf-and-viewport"> <LayoutRow class="shelf-and-table">
<LayoutCol class="shelf"> <LayoutCol class="shelf">
{#if !graphViewOverlayOpen} {#if !graphViewOverlayOpen}
<LayoutCol class="tools" scrollableY={true}> <LayoutCol class="tools" scrollableY={true}>
<WidgetLayout layout={$document.toolShelfLayout} /> <WidgetLayout layout={$document.toolShelfLayout} />
</LayoutCol> </LayoutCol>
{/if} {/if}
<LayoutCol class="spacer" /> <LayoutCol class="spacer" />
<LayoutCol class="shelf-bottom-widgets">
<LayoutCol class="widgets-below-shelf">
<WidgetLayout layout={$document.graphViewOverlayButtonLayout} /> <WidgetLayout layout={$document.graphViewOverlayButtonLayout} />
<WidgetLayout layout={$document.workingColorsLayout} /> <WidgetLayout layout={$document.workingColorsLayout} />
</LayoutCol> </LayoutCol>
</LayoutCol> </LayoutCol>
<LayoutCol class="viewport"> <LayoutCol class="table">
<LayoutRow class="bar-area top-ruler"> <LayoutRow class="ruler-or-scrollbar top-ruler">
<CanvasRuler origin={rulerOrigin.x} majorMarkSpacing={rulerSpacing} numberInterval={rulerInterval} direction="Horizontal" bind:this={rulerHorizontal} /> <CanvasRuler origin={rulerOrigin.x} majorMarkSpacing={rulerSpacing} numberInterval={rulerInterval} direction="Horizontal" bind:this={rulerHorizontal} />
</LayoutRow> </LayoutRow>
<LayoutRow class="canvas-area"> <LayoutRow class="viewport-container">
<LayoutCol class="bar-area"> <LayoutCol class="ruler-or-scrollbar">
<CanvasRuler origin={rulerOrigin.y} majorMarkSpacing={rulerSpacing} numberInterval={rulerInterval} direction="Vertical" bind:this={rulerVertical} /> <CanvasRuler origin={rulerOrigin.y} majorMarkSpacing={rulerSpacing} numberInterval={rulerInterval} direction="Vertical" bind:this={rulerVertical} />
</LayoutCol> </LayoutCol>
<LayoutCol class="canvas-area" styles={{ cursor: canvasCursor }}> <LayoutCol class="viewport-container" styles={{ cursor: canvasCursor }}>
{#if cursorEyedropper} {#if cursorEyedropper}
<EyedropperPreview <EyedropperPreview
colorChoice={cursorEyedropperPreviewColorChoice} colorChoice={cursorEyedropperPreviewColorChoice}
@ -482,7 +478,7 @@
y={cursorTop} y={cursorTop}
/> />
{/if} {/if}
<div class="canvas" on:pointerdown={(e) => canvasPointerDown(e)} on:dragover={(e) => e.preventDefault()} on:drop={(e) => pasteFile(e)} bind:this={canvasContainer} data-canvas> <div class="viewport" on:pointerdown={(e) => canvasPointerDown(e)} on:dragover={(e) => e.preventDefault()} on:drop={(e) => pasteFile(e)} bind:this={viewport} data-viewport>
<svg class="artboards" style:width={canvasWidthCSS} style:height={canvasHeightCSS}> <svg class="artboards" style:width={canvasWidthCSS} style:height={canvasHeightCSS}>
{@html artboardSvg} {@html artboardSvg}
</svg> </svg>
@ -503,11 +499,11 @@
{/if} {/if}
</div> </div>
</div> </div>
<div class="graph-view" class:open={graphViewOverlayOpen} style:--fade-artwork="80%"> <div class="graph-view" class:open={graphViewOverlayOpen} style:--fade-artwork="80%" data-graph>
<Graph /> <Graph />
</div> </div>
</LayoutCol> </LayoutCol>
<LayoutCol class="bar-area right-scrollbar"> <LayoutCol class="ruler-or-scrollbar right-scrollbar">
<PersistentScrollbar <PersistentScrollbar
direction="Vertical" direction="Vertical"
handleLength={scrollbarSize.y} handleLength={scrollbarSize.y}
@ -517,7 +513,7 @@
/> />
</LayoutCol> </LayoutCol>
</LayoutRow> </LayoutRow>
<LayoutRow class="bar-area bottom-scrollbar"> <LayoutRow class="ruler-or-scrollbar bottom-scrollbar">
<PersistentScrollbar <PersistentScrollbar
direction="Horizontal" direction="Horizontal"
handleLength={scrollbarSize.x} handleLength={scrollbarSize.x}
@ -550,7 +546,7 @@
} }
} }
.shelf-and-viewport { .shelf-and-table {
.shelf { .shelf {
width: 32px; width: 32px;
flex: 0 0 auto; flex: 0 0 auto;
@ -587,7 +583,7 @@
min-height: 20px; min-height: 20px;
} }
.widgets-below-shelf { .shelf-bottom-widgets {
flex: 0 0 auto; flex: 0 0 auto;
.widget-layout:first-of-type { .widget-layout:first-of-type {
@ -613,10 +609,10 @@
} }
} }
.viewport { .table {
flex: 1 1 100%; flex: 1 1 100%;
.bar-area { .ruler-or-scrollbar {
flex: 0 0 auto; flex: 0 0 auto;
} }
@ -633,11 +629,11 @@
margin-right: 16px; margin-right: 16px;
} }
.canvas-area { .viewport-container {
flex: 1 1 100%; flex: 1 1 100%;
position: relative; position: relative;
.canvas { .viewport {
background: var(--color-2-mildblack); background: var(--color-2-mildblack);
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@ -635,6 +635,8 @@
style:--offset-left={(node.position?.x || 0) + (selected.includes(node.id) ? draggingNodes?.roundX || 0 : 0)} style:--offset-left={(node.position?.x || 0) + (selected.includes(node.id) ? draggingNodes?.roundX || 0 : 0)}
style:--offset-top={(node.position?.y || 0) + (selected.includes(node.id) ? draggingNodes?.roundY || 0 : 0)} style:--offset-top={(node.position?.y || 0) + (selected.includes(node.id) ? draggingNodes?.roundY || 0 : 0)}
style:--clip-path-id={`url(#${clipPathId})`} style:--clip-path-id={`url(#${clipPathId})`}
style:--data-color={`var(--color-data-${node.primaryOutput?.dataType || "general"})`}
style:--data-color-dim={`var(--color-data-${node.primaryOutput?.dataType || "general"}-dim)`}
data-node={node.id} data-node={node.id}
> >
<div class="node-chain" /> <div class="node-chain" />
@ -707,6 +709,8 @@
style:--offset-left={(node.position?.x || 0) + (selected.includes(node.id) ? draggingNodes?.roundX || 0 : 0)} style:--offset-left={(node.position?.x || 0) + (selected.includes(node.id) ? draggingNodes?.roundX || 0 : 0)}
style:--offset-top={(node.position?.y || 0) + (selected.includes(node.id) ? draggingNodes?.roundY || 0 : 0)} style:--offset-top={(node.position?.y || 0) + (selected.includes(node.id) ? draggingNodes?.roundY || 0 : 0)}
style:--clip-path-id={`url(#${clipPathId})`} style:--clip-path-id={`url(#${clipPathId})`}
style:--data-color={`var(--color-data-${node.primaryOutput?.dataType || "general"})`}
style:--data-color-dim={`var(--color-data-${node.primaryOutput?.dataType || "general"}-dim)`}
data-node={node.id} data-node={node.id}
> >
<!-- Primary row --> <!-- Primary row -->
@ -901,11 +905,12 @@
left: calc(var(--offset-left) * 24px); left: calc(var(--offset-left) * 24px);
top: calc(var(--offset-top) * 24px); top: calc(var(--offset-top) * 24px);
// TODO: Reenable the `transition` property below after dealing with all edge cases where the wires need to be updated until the transition is complete // TODO: Reenable the `transition` property below after dealing with all edge cases where the wires need to be updated until the transition is complete
// transition: top 0.1s cubic-bezier(0, 0, 0.2, 1), left 0.1s cubic-bezier(0, 0, 0.2, 1); // Update `DRAG_SMOOTHING_TIME` in the JS above // transition: top 0.1s cubic-bezier(0, 0, 0.2, 1), left 0.1s cubic-bezier(0, 0, 0.2, 1); // Update `DRAG_SMOOTHING_TIME` in the JS above.
// TODO: Find a solution for this having no effect in Firefox due to a browser bug caused when the two ancestor // TODO: Reenable the `backdrop-filter` property once a solution can be found for the black whole-page flickering problems it causes in Chrome.
// elements, `.graph` and `.panel`, have the simultaneous pairing of `overflow: hidden` and `border-radius`. // TODO: Additionally, find a solution for this having no effect in Firefox due to a browser bug caused when the two
// ancestor elements, `.graph` and `.panel`, each have the simultaneous pairing of `overflow: hidden` and `border-radius`.
// See: https://stackoverflow.com/questions/75137879/bug-with-backdrop-filter-in-firefox // See: https://stackoverflow.com/questions/75137879/bug-with-backdrop-filter-in-firefox
backdrop-filter: blur(4px); // backdrop-filter: blur(4px);
background: rgba(0, 0, 0, 0.33); background: rgba(0, 0, 0, 0.33);
&::after { &::after {
@ -939,7 +944,7 @@
} }
&.previewed::after { &.previewed::after {
border: 1px dashed var(--color-data-vector); border: 1px dashed var(--data-color);
} }
.ports { .ports {
@ -1016,7 +1021,7 @@
.thumbnail { .thumbnail {
background: var(--color-2-mildblack); background: var(--color-2-mildblack);
border: 1px solid var(--color-data-vector-dim); border: 1px solid var(--data-color-dim);
border-radius: 2px; border-radius: 2px;
position: relative; position: relative;
box-sizing: border-box; box-sizing: border-box;
@ -1081,7 +1086,7 @@
top: calc((var(--offset-top) + 0.5) * 24px); top: calc((var(--offset-top) + 0.5) * 24px);
&::after { &::after {
border: 1px solid var(--color-data-vector-dim); border: 1px solid var(--data-color-dim);
border-radius: 2px; border-radius: 2px;
} }

View File

@ -5,7 +5,6 @@
import Panel from "@graphite/components/window/workspace/Panel.svelte"; import Panel from "@graphite/components/window/workspace/Panel.svelte";
import { getContext } from "svelte"; import { getContext } from "svelte";
import type { Editor } from "@graphite/wasm-communication/editor"; import type { Editor } from "@graphite/wasm-communication/editor";
import type { WorkspaceState } from "@graphite/state-providers/workspace";
import type { PortfolioState } from "@graphite/state-providers/portfolio"; import type { PortfolioState } from "@graphite/state-providers/portfolio";
import type { DialogState } from "@graphite/state-providers/dialog"; import type { DialogState } from "@graphite/state-providers/dialog";
import type { FrontendDocumentDetails } from "@graphite/wasm-communication/messages"; import type { FrontendDocumentDetails } from "@graphite/wasm-communication/messages";
@ -35,7 +34,6 @@
}); });
const editor = getContext<Editor>("editor"); const editor = getContext<Editor>("editor");
const workspace = getContext<WorkspaceState>("workspace");
const portfolio = getContext<PortfolioState>("portfolio"); const portfolio = getContext<PortfolioState>("portfolio");
const dialog = getContext<DialogState>("dialog"); const dialog = getContext<DialogState>("dialog");

View File

@ -136,8 +136,8 @@ export function createInputManager(editor: Editor, dialog: DialogState, document
if (!viewportPointerInteractionOngoing && inFloatingMenu) return; if (!viewportPointerInteractionOngoing && inFloatingMenu) return;
const { target } = e; const { target } = e;
const newInCanvas = (target instanceof Element && target.closest("[data-canvas]")) instanceof Element && !targetIsTextField(window.document.activeElement || undefined); const newInCanvasArea = (target instanceof Element && target.closest("[data-viewport], [data-graph]")) instanceof Element && !targetIsTextField(window.document.activeElement || undefined);
if (newInCanvas && !canvasFocused) { if (newInCanvasArea && !canvasFocused) {
canvasFocused = true; canvasFocused = true;
app?.focus(); app?.focus();
} }
@ -148,7 +148,7 @@ export function createInputManager(editor: Editor, dialog: DialogState, document
function onPointerDown(e: PointerEvent): void { function onPointerDown(e: PointerEvent): void {
const { target } = e; const { target } = e;
const isTargetingCanvas = target instanceof Element && target.closest("[data-canvas]"); const isTargetingCanvas = target instanceof Element && target.closest("[data-viewport]");
const inDialog = target instanceof Element && target.closest("[data-dialog-modal] [data-floating-menu-content]"); const inDialog = target instanceof Element && target.closest("[data-dialog-modal] [data-floating-menu-content]");
const inTextInput = target === textToolInteractiveInputElement; const inTextInput = target === textToolInteractiveInputElement;
@ -194,7 +194,7 @@ export function createInputManager(editor: Editor, dialog: DialogState, document
function onWheelScroll(e: WheelEvent): void { function onWheelScroll(e: WheelEvent): void {
const { target } = e; const { target } = e;
const isTargetingCanvas = target instanceof Element && target.closest("[data-canvas]"); const isTargetingCanvas = target instanceof Element && target.closest("[data-viewport]");
// Redirect vertical scroll wheel movement into a horizontal scroll on a horizontally scrollable element // Redirect vertical scroll wheel movement into a horizontal scroll on a horizontally scrollable element
// There seems to be no possible way to properly employ the browser's smooth scrolling interpolation // There seems to be no possible way to properly employ the browser's smooth scrolling interpolation
@ -226,7 +226,7 @@ export function createInputManager(editor: Editor, dialog: DialogState, document
// Window events // Window events
function onWindowResize(container: HTMLElement): void { function onWindowResize(container: HTMLElement): void {
const viewports = Array.from(container.querySelectorAll("[data-canvas]")); const viewports = Array.from(container.querySelectorAll("[data-viewport]"));
const boundsOfViewports = viewports.map((canvas) => { const boundsOfViewports = viewports.map((canvas) => {
const bounds = canvas.getBoundingClientRect(); const bounds = canvas.getBoundingClientRect();
return [bounds.left, bounds.top, bounds.right, bounds.bottom]; return [bounds.left, bounds.top, bounds.right, bounds.bottom];

View File

@ -1,18 +0,0 @@
/* eslint-disable max-classes-per-file */
import {writable} from "svelte/store";
import { type Editor } from "@graphite/wasm-communication/editor";
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export function createWorkspaceState(editor: Editor) {
const { subscribe, update } = writable({});
// Set up message subscriptions on creation
return {
subscribe,
};
}
export type WorkspaceState = ReturnType<typeof createWorkspaceState>;