diff --git a/packages/dev/core/src/FrameGraph/Node/nodeRenderGraph.ts b/packages/dev/core/src/FrameGraph/Node/nodeRenderGraph.ts index 4d79f407aca..151f8e11651 100644 --- a/packages/dev/core/src/FrameGraph/Node/nodeRenderGraph.ts +++ b/packages/dev/core/src/FrameGraph/Node/nodeRenderGraph.ts @@ -452,6 +452,7 @@ export class NodeRenderGraph { blockId: number; x: number; y: number; + isCollapsed: boolean; }[] = source.locations || source.editorData.locations; for (const location of locations) { diff --git a/packages/dev/core/src/Materials/Node/nodeMaterial.ts b/packages/dev/core/src/Materials/Node/nodeMaterial.ts index 08e67abfac1..32240159de2 100644 --- a/packages/dev/core/src/Materials/Node/nodeMaterial.ts +++ b/packages/dev/core/src/Materials/Node/nodeMaterial.ts @@ -2395,6 +2395,7 @@ export class NodeMaterial extends PushMaterial { blockId: number; x: number; y: number; + isCollapsed: boolean; }[] = source.locations || source.editorData.locations; for (const location of locations) { diff --git a/packages/dev/core/src/Meshes/Node/nodeGeometry.ts b/packages/dev/core/src/Meshes/Node/nodeGeometry.ts index dadaa2e421c..66c03100db1 100644 --- a/packages/dev/core/src/Meshes/Node/nodeGeometry.ts +++ b/packages/dev/core/src/Meshes/Node/nodeGeometry.ts @@ -439,6 +439,7 @@ export class NodeGeometry { blockId: number; x: number; y: number; + isCollapsed: boolean; }[] = source.locations || source.editorData.locations; for (const location of locations) { diff --git a/packages/dev/sharedUiComponents/src/imgs/dropdownArrowIcon_white.svg b/packages/dev/sharedUiComponents/src/imgs/dropdownArrowIcon_white.svg new file mode 100644 index 00000000000..a6cec79ec5b --- /dev/null +++ b/packages/dev/sharedUiComponents/src/imgs/dropdownArrowIcon_white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/dev/sharedUiComponents/src/nodeGraphSystem/graphCanvas.tsx b/packages/dev/sharedUiComponents/src/nodeGraphSystem/graphCanvas.tsx index 5df5e11e737..139eb698d32 100644 --- a/packages/dev/sharedUiComponents/src/nodeGraphSystem/graphCanvas.tsx +++ b/packages/dev/sharedUiComponents/src/nodeGraphSystem/graphCanvas.tsx @@ -1446,6 +1446,9 @@ export class GraphCanvasComponent extends React.Component= 0 ? `${executionTime.toFixed(2)} ms` : ""; this.content.prepareHeaderIcon(this._headerIcon, this._headerIconImg); - if (this._headerIconImg.src) { - this._header.classList.add(localStyles["headerWithIcon"]); - } } private _onDown(evt: PointerEvent) { // Check if this is coming from the port - if (evt.target && (evt.target as HTMLElement).nodeName === "IMG") { + if (evt.target && (evt.target as HTMLElement).nodeName === "IMG" && (evt.target as HTMLElement).draggable) { return; } @@ -563,6 +567,48 @@ export class GraphNode { ForceRebuild(source, this._stateManager, propertyName, notifiers); } + private _isCollapsed = false; + + /** + * Collapse the node + */ + public collapse() { + this._headerCollapse.classList.add(localStyles.collapsed); + this._inputPorts + .filter((p) => !p.portData.isConnected) + .forEach((p) => { + p.container.classList.add(commonStyles.hidden); + }); + + this._outputPorts + .filter((p) => !p.portData.isConnected) + .forEach((p) => { + p.container.classList.add(commonStyles.hidden); + }); + + this._refreshLinks(); + } + + /** + * Expand the node + */ + public expand() { + this._headerCollapse.classList.remove(localStyles.collapsed); + this._inputPorts + .filter((p) => !p.portData.isConnected) + .forEach((p) => { + p.container.classList.remove(commonStyles.hidden); + }); + + this._outputPorts + .filter((p) => !p.portData.isConnected) + .forEach((p) => { + p.container.classList.remove(commonStyles.hidden); + }); + + this._refreshLinks(); + } + public appendVisual(root: HTMLDivElement, owner: GraphCanvasComponent) { this._ownerCanvas = owner; @@ -592,9 +638,31 @@ export class GraphNode { this._headerIcon = root.ownerDocument!.createElement("div"); this._headerIcon.classList.add(localStyles.headerIcon); this._headerIconImg = root.ownerDocument!.createElement("img"); + this._headerIconImg.draggable = false; this._headerIcon.appendChild(this._headerIconImg); this._headerContainer.appendChild(this._headerIcon); + if (this.content.inputs.length > 1 || this.content.outputs.length > 1) { + this._headerCollapse = root.ownerDocument!.createElement("div"); + this._headerCollapse.classList.add(localStyles.headerCollapse); + this._headerCollapseImg = root.ownerDocument!.createElement("img"); + this._headerCollapseImg.src = dropdownArrowIcon; + this._headerCollapseImg.draggable = false; + this._headerCollapse.appendChild(this._headerCollapseImg); + this._headerContainer.appendChild(this._headerCollapse); + this._headerCollapse.addEventListener("pointerup", (evt) => evt.stopPropagation()); + this._headerCollapse.addEventListener("pointermove", (evt) => evt.stopPropagation()); + this._headerCollapse.addEventListener("pointerdown", (evt) => { + this._isCollapsed = !this._isCollapsed; + if (this._isCollapsed) { + this.collapse(); + } else { + this.expand(); + } + evt.stopPropagation(); + }); + } + this._selectionBorder = root.ownerDocument!.createElement("div"); this._selectionBorder.classList.add("selection-border"); this._visual.appendChild(this._selectionBorder); @@ -630,7 +698,7 @@ export class GraphNode { this._visual.appendChild(this._comments); - // Comments + // Execution time this._executionTime = root.ownerDocument!.createElement("div"); this._executionTime.classList.add(localStyles.executionTime); diff --git a/packages/dev/sharedUiComponents/src/nodeGraphSystem/interfaces/nodeLocationInfo.ts b/packages/dev/sharedUiComponents/src/nodeGraphSystem/interfaces/nodeLocationInfo.ts index f3028bc18ea..2a1e7856c50 100644 --- a/packages/dev/sharedUiComponents/src/nodeGraphSystem/interfaces/nodeLocationInfo.ts +++ b/packages/dev/sharedUiComponents/src/nodeGraphSystem/interfaces/nodeLocationInfo.ts @@ -2,6 +2,7 @@ export interface INodeLocationInfo { blockId: number; x: number; y: number; + isCollapsed: boolean; } export interface IFrameData { diff --git a/packages/dev/sharedUiComponents/src/nodeGraphSystem/nodePort.ts b/packages/dev/sharedUiComponents/src/nodeGraphSystem/nodePort.ts index 433ef4b60a1..529b2602fd3 100644 --- a/packages/dev/sharedUiComponents/src/nodeGraphSystem/nodePort.ts +++ b/packages/dev/sharedUiComponents/src/nodeGraphSystem/nodePort.ts @@ -12,6 +12,7 @@ import localStyles from "./nodePort.modules.scss"; export class NodePort { protected _element: HTMLDivElement; + protected _portContainer: HTMLElement; protected _img: HTMLImageElement; protected _pip: HTMLDivElement; protected _stateManager: StateManager; @@ -29,6 +30,14 @@ export class NodePort { return this._element; } + public get container(): HTMLElement { + if (this.delegatedPort) { + return this.delegatedPort.container; + } + + return this._portContainer; + } + public get portName() { return this.portData.name; } @@ -106,6 +115,7 @@ export class NodePort { public node: GraphNode, stateManager: StateManager ) { + this._portContainer = portContainer; this._element = portContainer.ownerDocument!.createElement("div"); this._element.classList.add(commonStyles.port); portContainer.appendChild(this._element); diff --git a/packages/tools/nodeEditor/src/serializationTools.ts b/packages/tools/nodeEditor/src/serializationTools.ts index 65672174724..59b5fd9868f 100644 --- a/packages/tools/nodeEditor/src/serializationTools.ts +++ b/packages/tools/nodeEditor/src/serializationTools.ts @@ -22,6 +22,7 @@ export class SerializationTools { blockId: block.uniqueId, x: node ? node.x : 0, y: node ? node.y : 0, + isCollapsed: node ? node.isCollapsed : false, }); } diff --git a/packages/tools/nodeGeometryEditor/src/serializationTools.ts b/packages/tools/nodeGeometryEditor/src/serializationTools.ts index d6fd680eaab..aafc78118b5 100644 --- a/packages/tools/nodeGeometryEditor/src/serializationTools.ts +++ b/packages/tools/nodeGeometryEditor/src/serializationTools.ts @@ -20,6 +20,7 @@ export class SerializationTools { blockId: block.uniqueId, x: node ? node.x : 0, y: node ? node.y : 0, + isCollapsed: node ? node.isCollapsed : false, }); } diff --git a/packages/tools/nodeRenderGraphEditor/src/serializationTools.ts b/packages/tools/nodeRenderGraphEditor/src/serializationTools.ts index cb4401bd3d3..798b59f891c 100644 --- a/packages/tools/nodeRenderGraphEditor/src/serializationTools.ts +++ b/packages/tools/nodeRenderGraphEditor/src/serializationTools.ts @@ -20,6 +20,7 @@ export class SerializationTools { blockId: block.uniqueId, x: node ? node.x : 0, y: node ? node.y : 0, + isCollapsed: node ? node.isCollapsed : false, }); }