From 075e5d67aedacde8a39a388567dc95b6dcd7552e Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 9 Dec 2025 19:16:31 -0800 Subject: [PATCH] Improve data type organization --- .../src/messages/frontend/frontend_message.rs | 17 ++++---- .../document/document_message_handler.rs | 9 ++-- .../node_graph/node_graph_message_handler.rs | 42 ++++++++----------- .../document/node_graph/utility_types.rs | 12 +++++- frontend/src/components/views/Graph.svelte | 28 +++++++++---- frontend/src/messages.ts | 38 ++++++++++------- frontend/src/state-providers/node-graph.ts | 17 ++++---- 7 files changed, 92 insertions(+), 71 deletions(-) diff --git a/editor/src/messages/frontend/frontend_message.rs b/editor/src/messages/frontend/frontend_message.rs index e6c724069f..8fec80e37e 100644 --- a/editor/src/messages/frontend/frontend_message.rs +++ b/editor/src/messages/frontend/frontend_message.rs @@ -3,10 +3,11 @@ use crate::messages::app_window::app_window_message_handler::AppWindowPlatform; use crate::messages::input_mapper::utility_types::misc::ActionShortcut; use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::portfolio::document::node_graph::utility_types::{ - BoxSelection, ContextMenuInformation, FrontendClickTargets, FrontendGraphInput, FrontendGraphOutput, FrontendNode, FrontendNodeType, NodeGraphErrorDiagnostic, Transform, + ContextMenuInformation, FrontendClickTargets, FrontendGraphInput, FrontendGraphOutput, FrontendNode, FrontendNodeType, NodeGraphErrorDiagnostic, NodeGraphSelectionBox, NodeGraphTransform, + WirePathInProgress, }; use crate::messages::portfolio::document::utility_types::nodes::{JsRawBuffer, LayerPanelEntry, RawBuffer}; -use crate::messages::portfolio::document::utility_types::wires::{WirePath, WirePathUpdate}; +use crate::messages::portfolio::document::utility_types::wires::WirePathUpdate; use crate::messages::prelude::*; use glam::IVec2; use graph_craft::document::NodeId; @@ -167,9 +168,9 @@ pub enum FrontendMessage { #[serde(rename = "inSelectedNetwork")] in_selected_network: bool, }, - UpdateBox { - #[serde(rename = "box")] - box_selection: Option, + UpdateNodeGraphSelectionBox { + #[serde(rename = "selectionBox")] + selection_box: Option, }, UpdateContextMenuInformation { #[serde(rename = "contextMenuInformation")] @@ -298,7 +299,7 @@ pub enum FrontendMessage { selected: Vec, }, UpdateNodeGraphTransform { - transform: Transform, + transform: NodeGraphTransform, }, UpdateNodeThumbnail { id: NodeId, @@ -318,8 +319,8 @@ pub enum FrontendMessage { diff: Vec, }, UpdateWirePathInProgress { - #[serde(rename = "wirePath")] - wire_path: Option, + #[serde(rename = "wirePathInProgress")] + wire_path_in_progress: Option, }, UpdateWelcomeScreenButtonsLayout { diff: Vec, diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index 180910bac5..4ad632a264 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -1,5 +1,5 @@ use super::node_graph::document_node_definitions; -use super::node_graph::utility_types::Transform; +use super::node_graph::utility_types::NodeGraphTransform; use super::utility_types::error::EditorError; use super::utility_types::misc::{GroupFolderType, SNAP_FUNCTIONS_FOR_BOUNDING_BOXES, SNAP_FUNCTIONS_FOR_PATHS, SnappingOptions, SnappingState}; use super::utility_types::network_interface::{self, NodeNetworkInterface, TransactionStatus}; @@ -22,6 +22,7 @@ use crate::messages::portfolio::document::utility_types::network_interface::{Flo use crate::messages::portfolio::document::utility_types::nodes::RawBuffer; use crate::messages::portfolio::utility_types::{FontCatalog, PanelType, PersistentData}; use crate::messages::prelude::*; + use crate::messages::tool::common_functionality::graph_modification_utils::{self, get_blend_mode, get_fill, get_opacity}; use crate::messages::tool::tool_messages::select_tool::SelectToolPointerKeys; use crate::messages::tool::tool_messages::tool_prelude::Key; @@ -485,7 +486,7 @@ impl MessageHandler> for DocumentMes responses.add(NodeGraphMessage::SelectedNodesSet { nodes: self.node_graph_handler.selection_before_pointer_down.clone(), }); - responses.add(FrontendMessage::UpdateBox { box_selection: None }); + responses.add(FrontendMessage::UpdateNodeGraphSelectionBox { selection_box: None }); } // Abort wire in progress of being connected else if self.node_graph_handler.wire_in_progress_from_connector.is_some() { @@ -493,7 +494,7 @@ impl MessageHandler> for DocumentMes self.node_graph_handler.wire_in_progress_to_connector = None; self.node_graph_handler.wire_in_progress_type = FrontendGraphDataType::General; - responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path: None }); + responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path_in_progress: None }); responses.add(DocumentMessage::AbortTransaction); } // Close the context menu if it's open @@ -1525,7 +1526,7 @@ impl MessageHandler> for DocumentMes responses.add(NodeGraphMessage::UpdateImportsExports); responses.add(FrontendMessage::UpdateNodeGraphTransform { - transform: Transform { + transform: NodeGraphTransform { scale: transform.matrix2.x_axis.x, x: transform.translation.x, y: transform.translation.y, diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs index c26b21af5c..a6876cbe4d 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs @@ -1,5 +1,5 @@ use super::node_properties; -use super::utility_types::{BoxSelection, ContextMenuInformation, DragStart, FrontendNode}; +use super::utility_types::{ContextMenuInformation, DragStart, FrontendNode, NodeGraphSelectionBox}; use crate::consts::GRID_SIZE; use crate::messages::clipboard::utility_types::ClipboardContent; use crate::messages::input_mapper::utility_types::macros::{action_shortcut, action_shortcut_manual}; @@ -9,14 +9,14 @@ use crate::messages::portfolio::document::graph_operation::utility_types::Modify use crate::messages::portfolio::document::node_graph::document_node_definitions::{ DefinitionIdentifier, NodePropertiesContext, resolve_document_node_type, resolve_network_node_type, resolve_proto_node_type, }; -use crate::messages::portfolio::document::node_graph::utility_types::{ContextMenuData, Direction, FrontendGraphDataType, NodeGraphErrorDiagnostic}; +use crate::messages::portfolio::document::node_graph::utility_types::{ContextMenuData, Direction, FrontendGraphDataType, NodeGraphErrorDiagnostic, WirePathInProgress}; use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier; use crate::messages::portfolio::document::utility_types::misc::GroupFolderType; use crate::messages::portfolio::document::utility_types::network_interface::{ self, FlowType, InputConnector, NodeNetworkInterface, NodeTemplate, NodeTypePersistentMetadata, OutputConnector, Previewing, }; use crate::messages::portfolio::document::utility_types::nodes::{CollapsedLayers, LayerPanelEntry}; -use crate::messages::portfolio::document::utility_types::wires::{GraphWireStyle, WirePath, WirePathUpdate, build_vector_wire}; +use crate::messages::portfolio::document::utility_types::wires::{GraphWireStyle, WirePathUpdate, build_vector_wire}; use crate::messages::prelude::*; use crate::messages::tool::common_functionality::auto_panning::AutoPanning; use crate::messages::tool::common_functionality::graph_modification_utils::get_clip_mode; @@ -329,7 +329,7 @@ impl<'a> MessageHandler> for NodeG self.wire_in_progress_to_connector = None; self.wire_in_progress_type = FrontendGraphDataType::General; } - responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path: None }); + responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path_in_progress: None }); responses.add(FrontendMessage::UpdateContextMenuInformation { context_menu_information: self.context_menu.clone(), }); @@ -790,7 +790,7 @@ impl<'a> MessageHandler> for NodeG responses.add(NodeGraphMessage::SelectedNodesSet { nodes: self.selection_before_pointer_down.clone(), }); - responses.add(FrontendMessage::UpdateBox { box_selection: None }); + responses.add(FrontendMessage::UpdateNodeGraphSelectionBox { selection_box: None }); return; } // Abort dragging a wire @@ -800,7 +800,8 @@ impl<'a> MessageHandler> for NodeG self.wire_in_progress_type = FrontendGraphDataType::General; responses.add(DocumentMessage::AbortTransaction); - responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path: None }); + responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path_in_progress: None }); + return; } @@ -885,7 +886,7 @@ impl<'a> MessageHandler> for NodeG responses.add(FrontendMessage::UpdateContextMenuInformation { context_menu_information: self.context_menu.clone(), }); - responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path: None }); + responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path_in_progress: None }); } // Toggle visibility of clicked node and return @@ -1094,14 +1095,14 @@ impl<'a> MessageHandler> for NodeG to_connector_is_layer, GraphWireStyle::Direct, ); - let path_string = vector_wire.to_svg(); - let wire_path = WirePath { - path_string, + let wire_path = WirePathInProgress { + wire: vector_wire.to_svg(), data_type: self.wire_in_progress_type, thick: false, - dashed: false, }; - responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path: Some(wire_path) }); + responses.add(FrontendMessage::UpdateWirePathInProgress { + wire_path_in_progress: Some(wire_path), + }); } } else if let Some((drag_start, dragged)) = &mut self.drag_start { if drag_start.start_x != point.x || drag_start.start_y != point.y { @@ -1431,8 +1432,8 @@ impl<'a> MessageHandler> for NodeG self.reordering_import = None; responses.add(DocumentMessage::EndTransaction); - responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path: None }); - responses.add(FrontendMessage::UpdateBox { box_selection: None }); + responses.add(FrontendMessage::UpdateWirePathInProgress { wire_path_in_progress: None }); + responses.add(FrontendMessage::UpdateNodeGraphSelectionBox { selection_box: None }); responses.add(FrontendMessage::UpdateImportReorderIndex { index: None }); responses.add(FrontendMessage::UpdateExportReorderIndex { index: None }); self.update_node_graph_hints(responses); @@ -1926,15 +1927,6 @@ impl<'a> MessageHandler> for NodeG } NodeGraphMessage::UpdateBoxSelection => { if let Some((box_selection_start, _)) = self.box_selection_start { - // The mouse button was released but we missed the pointer up event - // if ((e.buttons & 1) === 0) { - // completeBoxSelection(); - // boxSelection = undefined; - // } else if ((e.buttons & 2) !== 0) { - // editor.handle.selectNodes(new BigUint64Array(previousSelection)); - // boxSelection = undefined; - // } - let Some(network_metadata) = network_interface.network_metadata(selection_network_path) else { log::error!("Could not get network metadata in UpdateBoxSelection"); return; @@ -1942,7 +1934,7 @@ impl<'a> MessageHandler> for NodeG let box_selection_start_viewport = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.transform_point2(box_selection_start); - let box_selection = Some(BoxSelection { + let selection_box = Some(NodeGraphSelectionBox { start_x: box_selection_start_viewport.x.max(0.) as u32, start_y: box_selection_start_viewport.y.max(0.) as u32, end_x: ipp.mouse.position.x.max(0.) as u32, @@ -1987,7 +1979,7 @@ impl<'a> MessageHandler> for NodeG nodes: nodes.into_iter().collect::>(), }); } - responses.add(FrontendMessage::UpdateBox { box_selection }) + responses.add(FrontendMessage::UpdateNodeGraphSelectionBox { selection_box }) } } NodeGraphMessage::UpdateImportsExports => { diff --git a/editor/src/messages/portfolio/document/node_graph/utility_types.rs b/editor/src/messages/portfolio/document/node_graph/utility_types.rs index 12d6780fc1..2ec3de0135 100644 --- a/editor/src/messages/portfolio/document/node_graph/utility_types.rs +++ b/editor/src/messages/portfolio/document/node_graph/utility_types.rs @@ -119,14 +119,14 @@ pub struct DragStart { } #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)] -pub struct Transform { +pub struct NodeGraphTransform { pub scale: f64, pub x: f64, pub y: f64, } #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)] -pub struct BoxSelection { +pub struct NodeGraphSelectionBox { #[serde(rename = "startX")] pub start_x: u32, #[serde(rename = "startY")] @@ -137,6 +137,14 @@ pub struct BoxSelection { pub end_y: u32, } +#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)] +pub struct WirePathInProgress { + pub wire: String, + #[serde(rename = "dataType")] + pub data_type: FrontendGraphDataType, + pub thick: bool, +} + #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)] #[serde(tag = "type", content = "data")] pub enum ContextMenuData { diff --git a/frontend/src/components/views/Graph.svelte b/frontend/src/components/views/Graph.svelte index 740a8b84dc..29c5c1578d 100644 --- a/frontend/src/components/views/Graph.svelte +++ b/frontend/src/components/views/Graph.svelte @@ -14,6 +14,21 @@ import TextButton from "@graphite/components/widgets/buttons/TextButton.svelte"; import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte"; + // These components will continue to be rendered in svelte after the first stage of native node graph rendering. + // - Import and export ports + // - Wires to import and export + // - Wire in progress + // - Add Node context menu + // - Toggle Layer context menu + // - Error dialog + // - Node/Input/Output Tooltips + // - Solo drag grip tooltip + + // These elements will be not be rendered in svelte when rendering the native node graph. They are rendered below all other components + // - Dot grid background + // - Nodes/Layers + // - Wires between nodes/layers + const GRID_COLLAPSE_SPACING = 10; const GRID_SIZE = 24; const FADE_TRANSITION = { duration: 200, easing: cubicInOut }; @@ -618,11 +633,10 @@ {/each} {#if $nodeGraph.wirePathInProgress} {/if} @@ -768,13 +782,13 @@ -{#if $nodeGraph.box} +{#if $nodeGraph.selectionBox}
{/if} diff --git a/frontend/src/messages.ts b/frontend/src/messages.ts index 788b2a911e..4f4ce9afe4 100644 --- a/frontend/src/messages.ts +++ b/frontend/src/messages.ts @@ -25,14 +25,24 @@ 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; -} - export class UpdateClickTargets extends JsMessage { readonly clickTargets!: FrontendClickTargets | undefined; } +export class NodeGraphSelectionBox { + readonly startX!: number; + + readonly startY!: number; + + readonly endX!: number; + + readonly endY!: number; +} + +export class UpdateNodeGraphSelectionBox extends JsMessage { + readonly selectionBox!: NodeGraphSelectionBox | undefined; +} + export class UpdateImportsExports extends JsMessage { readonly imports!: (FrontendGraphOutput | undefined)[]; @@ -138,8 +148,14 @@ export class UpdateOpenDocumentsList extends JsMessage { readonly openDocuments!: OpenDocument[]; } +export class WirePathInProgress { + readonly wire!: string; + readonly thick!: boolean; + readonly dataType!: FrontendGraphDataType; +} + export class UpdateWirePathInProgress extends JsMessage { - readonly wirePath!: WirePath | undefined; + readonly wirePathInProgress!: WirePathInProgress | undefined; } export class OpenDocument { @@ -157,16 +173,6 @@ export class DocumentDetails { readonly isSaved!: boolean; } -export class Box { - readonly startX!: number; - - readonly startY!: number; - - readonly endX!: number; - - readonly endY!: number; -} - export type FrontendClickTargets = { readonly nodeClickTargets: string[]; readonly layerClickTargets: string[]; @@ -1694,7 +1700,6 @@ export const messageMakers: Record = { TriggerSelectionWrite, TriggerVisitLink, UpdateActiveDocument, - UpdateBox, UpdateClickTargets, UpdateContextMenuInformation, UpdateDataPanelLayout, @@ -1726,6 +1731,7 @@ export const messageMakers: Record = { UpdateNodeGraphErrorDiagnostic, UpdateNodeGraphNodes, UpdateNodeGraphSelection, + UpdateNodeGraphSelectionBox, UpdateNodeGraphTransform, UpdateNodeGraphWires, UpdateNodeThumbnail, diff --git a/frontend/src/state-providers/node-graph.ts b/frontend/src/state-providers/node-graph.ts index 2ddf46245e..8d716ad845 100644 --- a/frontend/src/state-providers/node-graph.ts +++ b/frontend/src/state-providers/node-graph.ts @@ -1,9 +1,8 @@ import { writable } from "svelte/store"; import { type Editor } from "@graphite/editor"; -import type { NodeGraphError } from "@graphite/messages"; +import type { NodeGraphError, NodeGraphSelectionBox, WirePathInProgress } from "@graphite/messages"; import { - type Box, type FrontendClickTargets, type ContextMenuInformation, type FrontendNode, @@ -11,7 +10,6 @@ import { type WirePath, ClearAllNodeGraphWires, SendUIMetadata, - UpdateBox, UpdateClickTargets, UpdateContextMenuInformation, UpdateInSelectedNetwork, @@ -27,14 +25,17 @@ import { UpdateNodeThumbnail, UpdateWirePathInProgress, UpdateNodeGraphErrorDiagnostic, + UpdateNodeGraphSelectionBox, } from "@graphite/messages"; export function createNodeGraphState(editor: Editor) { const { subscribe, update } = writable({ - box: undefined as Box | undefined, clickTargets: undefined as FrontendClickTargets | undefined, contextMenuInformation: undefined as ContextMenuInformation | undefined, error: undefined as NodeGraphError | undefined, + selectionBox: undefined as NodeGraphSelectionBox | undefined, + transform: { scale: 1, x: 0, y: 0 }, + wirePathInProgress: undefined as WirePathInProgress | undefined, layerWidths: new Map(), chainWidths: new Map(), hasLeftInputWire: new Map(), @@ -43,12 +44,10 @@ export function createNodeGraphState(editor: Editor) { visibleNodes: new Set(), /// The index is the exposed input index. The exports have a first key value of u32::MAX. wires: new Map>(), - wirePathInProgress: undefined as WirePath | undefined, nodeDescriptions: new Map(), nodeTypes: [] as FrontendNodeType[], thumbnails: new Map(), selected: [] as bigint[], - transform: { scale: 1, x: 0, y: 0 }, inSelectedNetwork: true, reorderImportIndex: undefined as number | undefined, reorderExportIndex: undefined as number | undefined, @@ -69,9 +68,9 @@ export function createNodeGraphState(editor: Editor) { return state; }); }); - editor.subscriptions.subscribeJsMessage(UpdateBox, (data) => { + editor.subscriptions.subscribeJsMessage(UpdateNodeGraphSelectionBox, (data) => { update((state) => { - state.box = data.box; + state.selectionBox = data.selectionBox; return state; }); }); @@ -184,7 +183,7 @@ export function createNodeGraphState(editor: Editor) { }); editor.subscriptions.subscribeJsMessage(UpdateWirePathInProgress, (data) => { update((state) => { - state.wirePathInProgress = data.wirePath; + state.wirePathInProgress = data.wirePathInProgress; return state; }); });