Migrate node graph UI interaction from frontend to backend (#1768)

* Click node using click targets based

* Display graph transform based on state stored in Rust, fix zoom and pan.

* Migrate node selection logic

* Move click targets and transform to NodeNetwork

* Keep click targets in sync with changes to node shape

* Click targets for import/export, add dragging

* Basic wire dragging

* complete wire dragging

* Add node selection box when dragging

* Fix zoom operations and dragging nodes

* Remove click targets from serialized data, fix EnterNestedNetwork

* WIP: Auto connect node when dragged on wire

* Finish auto connect node when dragged on wire

* Add context menus

* Improve layer width calculations and state

* Improve context menu state, various other improvements

* Close menu on escape

* Cleanup Graph.svelte

* Fix lock/hide tool tip shortcuts

* Clean up editor_api.rs, fix lock/hide layers

* Start transferring network and node metadata from NodeNetwork to the editor

* Transfer click targets to NodeGraphMessageHandler

* Fix infinite canvas

* Fix undo/redo, scrollbars, and fix warnings

* Unicode-3.0 license and code cleanup

* License fix

* formatting issue

* Enable DomRect

* Fix layer move crash

* Remove tests

* Ignore test

* formatting

* remove white dot

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
adamgerhant
2024-06-15 08:55:33 -07:00
committed by GitHub
co-authored by Keavon Chambers
parent cf01f522a8
commit 02360c7bc8
29 changed files with 2744 additions and 1257 deletions
@@ -25,6 +25,31 @@ export type XY = { x: number; y: number };
// for details about how to transform the JSON from wasm-bindgen into classes.
// ============================================================================
export class UpdateBox extends JsMessage {
readonly box!: Box | undefined;
}
const ContextTupleToVec2 = Transform((data) => {
if (data.obj.contextMenuInformation === undefined) return undefined;
const contextMenuCoordinates = { x: data.obj.contextMenuInformation.contextMenuCoordinates[0], y: data.obj.contextMenuInformation.contextMenuCoordinates[1] };
let contextMenuData = data.obj.contextMenuInformation.contextMenuData;
if (contextMenuData.ToggleLayer !== undefined) {
contextMenuData = { nodeId: contextMenuData.ToggleLayer.nodeId, currentlyIsNode: contextMenuData.ToggleLayer.currentlyIsNode };
}
return { contextMenuCoordinates, contextMenuData };
});
export class UpdateContextMenuInformation extends JsMessage {
@ContextTupleToVec2
readonly contextMenuInformation!: ContextMenuInformation | undefined;
}
const LayerWidths = Transform(({ obj }) => obj.layerWidths);
export class UpdateLayerWidths extends JsMessage {
@LayerWidths
readonly layerWidths!: Map<bigint, number>;
}
export class UpdateNodeGraph extends JsMessage {
@Type(() => FrontendNode)
readonly nodes!: FrontendNode[];
@@ -33,6 +58,10 @@ export class UpdateNodeGraph extends JsMessage {
readonly wires!: FrontendNodeWire[];
}
export class UpdateNodeGraphTransform extends JsMessage {
readonly transform!: NodeGraphTransform;
}
export class UpdateNodeTypes extends JsMessage {
@Type(() => FrontendNode)
readonly nodeTypes!: FrontendNodeType[];
@@ -58,6 +87,10 @@ export class UpdateSubgraphPath extends JsMessage {
readonly subgraphPath!: string[];
}
export class UpdateWirePathInProgress extends JsMessage {
readonly wirePath!: WirePath | undefined;
}
export class UpdateZoomWithScroll extends JsMessage {
readonly zoomWithScroll!: boolean;
}
@@ -84,6 +117,22 @@ export class FrontendDocumentDetails extends DocumentDetails {
readonly id!: bigint;
}
export class Box {
readonly startX!: number;
readonly startY!: number;
readonly endX!: number;
readonly endY!: number;
}
export type ContextMenuInformation = {
contextMenuCoordinates: XY;
contextMenuData: "CreateNode" | { nodeId: bigint; currentlyIsNode: boolean };
};
export type FrontendGraphDataType = "General" | "Raster" | "VectorData" | "Number" | "Graphic" | "Artboard";
export class FrontendGraphInput {
@@ -130,6 +179,8 @@ export class FrontendNode {
@TupleToVec2
readonly position!: XY | undefined;
//TODO: Store field for the width of the left node chain
readonly previewed!: boolean;
readonly visible!: boolean;
@@ -159,6 +210,19 @@ export class FrontendNodeType {
readonly category!: string;
}
export class NodeGraphTransform {
readonly scale!: number;
readonly x!: number;
readonly y!: number;
}
export class WirePath {
readonly pathString!: string;
readonly dataType!: FrontendGraphDataType;
readonly thick!: boolean;
readonly dashed!: boolean;
}
export class IndexedDbDocumentDetails extends DocumentDetails {
@Transform(({ value }: { value: bigint }) => value.toString())
id!: string;
@@ -1378,6 +1442,9 @@ export const messageMakers: Record<string, MessageMaker> = {
TriggerViewportResize,
TriggerVisitLink,
UpdateActiveDocument,
UpdateBox,
UpdateContextMenuInformation,
UpdateLayerWidths,
UpdateDialogButtons,
UpdateDialogColumn1,
UpdateDialogColumn2,
@@ -1396,6 +1463,7 @@ export const messageMakers: Record<string, MessageMaker> = {
UpdateNodeGraph,
UpdateNodeGraphBarLayout,
UpdateNodeGraphSelection,
UpdateNodeGraphTransform,
UpdateNodeThumbnail,
UpdateNodeTypes,
UpdateOpenDocumentsList,
@@ -1405,6 +1473,7 @@ export const messageMakers: Record<string, MessageMaker> = {
UpdateToolOptionsLayout,
UpdateToolShelfLayout,
UpdateWorkingColorsLayout,
UpdateWirePathInProgress,
UpdateZoomWithScroll,
} as const;
export type JsMessageType = keyof typeof messageMakers;