From 5a7d23015680c1042c47ee6fa1b766827b4be369 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Fri, 18 Aug 2023 14:26:59 -0700 Subject: [PATCH] Improve the layers UI in the node graph --- .../graph_operation_message_handler.rs | 2 +- .../src/components/panels/NodeGraph.svelte | 119 ++++++++++++------ 2 files changed, 84 insertions(+), 37 deletions(-) diff --git a/editor/src/messages/portfolio/document/node_graph/graph_operation_message_handler.rs b/editor/src/messages/portfolio/document/node_graph/graph_operation_message_handler.rs index 1ef21edd..07286e49 100644 --- a/editor/src/messages/portfolio/document/node_graph/graph_operation_message_handler.rs +++ b/editor/src/messages/portfolio/document/node_graph/graph_operation_message_handler.rs @@ -113,7 +113,7 @@ impl<'a> ModifyInputsContext<'a> { } let layer_node = resolve_document_node_type("Layer").expect("Node").to_document_node_default_inputs([], Default::default()); - let layer_node = self.insert_node_before(new_id, current_node, input_index, layer_node, IVec2::new(0, 3))?; + let layer_node = self.insert_node_before(new_id, current_node, input_index, layer_node, IVec2::new(-4, 3))?; Some(layer_node) } diff --git a/frontend/src/components/panels/NodeGraph.svelte b/frontend/src/components/panels/NodeGraph.svelte index f6cde7f5..c7fb6f03 100644 --- a/frontend/src/components/panels/NodeGraph.svelte +++ b/frontend/src/components/panels/NodeGraph.svelte @@ -180,12 +180,12 @@ const containerBounds = nodesContainer.getBoundingClientRect(); const outX = verticalOut ? outputBounds.x + outputBounds.width / 2 : outputBounds.x + outputBounds.width - 1; - const outY = verticalOut ? outputBounds.y + 1 : outputBounds.y + outputBounds.height / 2; + const outY = verticalOut ? outputBounds.y - 1 : outputBounds.y + outputBounds.height / 2; const outConnectorX = (outX - containerBounds.x) / transform.scale; const outConnectorY = (outY - containerBounds.y) / transform.scale; const inX = verticalIn ? inputBounds.x + inputBounds.width / 2 : inputBounds.x + 1; - const inY = verticalIn ? inputBounds.y + inputBounds.height - 1 : inputBounds.y + inputBounds.height / 2; + const inY = verticalIn ? inputBounds.y + inputBounds.height + 2 : inputBounds.y + inputBounds.height / 2; const inConnectorX = (inX - containerBounds.x) / transform.scale; const inConnectorY = (inY - containerBounds.y) / transform.scale; const horizontalGap = Math.abs(outConnectorX - inConnectorX); @@ -364,7 +364,7 @@ draggingNodes = { startX: e.x, startY: e.y, roundX: 0, roundY: 0 }; } - if (modifiedSelected) editor.instance.selectNodes(selected.length > 0 ? new BigUint64Array(selected) : null); + if (modifiedSelected) editor.instance.selectNodes(selected.length > 0 ? new BigUint64Array(selected) : undefined); return; } @@ -372,7 +372,7 @@ // Clicked on the graph background if (lmb && selected.length !== 0) { selected = []; - editor.instance.selectNodes(null); + editor.instance.selectNodes(undefined); } // LMB clicked on the graph background or MMB clicked anywhere @@ -524,15 +524,40 @@ nodeListLocation = undefined; } - function buildBorderMask(nodeWidth: number, primaryInputExists: boolean, parameters: number, primaryOutputExists: boolean, exposedOutputs: number): string { + function nodeBorderMask(nodeWidth: number, primaryInputExists: boolean, parameters: number, primaryOutputExists: boolean, exposedOutputs: number): string { const nodeHeight = Math.max(1 + parameters, 1 + exposedOutputs) * 24; const boxes: { x: number; y: number; width: number; height: number }[] = []; + + // Primary input if (primaryInputExists) boxes.push({ x: -8, y: 4, width: 16, height: 16 }); + // Parameter inputs for (let i = 0; i < parameters; i++) boxes.push({ x: -8, y: 4 + (i + 1) * 24, width: 16, height: 16 }); + + // Primary output if (primaryOutputExists) boxes.push({ x: nodeWidth - 8, y: 4, width: 16, height: 16 }); + // Exposed outputs for (let i = 0; i < exposedOutputs; i++) boxes.push({ x: nodeWidth - 8, y: 4 + (i + 1) * 24, width: 16, height: 16 }); + return borderMask(boxes, nodeWidth, nodeHeight); + } + + function layerBorderMask(nodeWidth: number): string { + const NODE_HEIGHT = 2 * 24; + const THUMBNAIL_WIDTH = 96; + const FUDGE = 2; + + const boxes: { x: number; y: number; width: number; height: number }[] = []; + // Left input + boxes.push({ x: -8, y: 16, width: 16, height: 16 }); + + // Thumbnail + boxes.push({ x: 24, y: -FUDGE, width: THUMBNAIL_WIDTH, height: NODE_HEIGHT + FUDGE * 2 }); + + return borderMask(boxes, nodeWidth, NODE_HEIGHT); + } + + function borderMask(boxes: { x: number; y: number; width: number; height: number }[], nodeWidth: number, nodeHeight: number): string { const rectangles = boxes.map((box) => `M${box.x},${box.y} L${box.x + box.width},${box.y} L${box.x + box.width},${box.y + box.height} L${box.x},${box.y + box.height}z`); return `M-2,-2 L${nodeWidth + 2},-2 L${nodeWidth + 2},${nodeHeight + 2} L-2,${nodeHeight + 2}z ${rectangles.join(" ")}`; } @@ -599,7 +624,7 @@ {#each linkPaths as { pathString, dataType, thick }} @@ -650,7 +675,7 @@ style:--data-color={`var(--color-data-${node.primaryOutput.dataType})`} style:--data-color-dim={`var(--color-data-${node.primaryOutput.dataType}-dim)`} > - + {/if} - +
- {node.displayName} + {node.displayName}
- + @@ -696,15 +721,15 @@
- {node.displayName} + {node.displayName}
{#if exposedInputsOutputs.length > 0}
{#each exposedInputsOutputs as parameter, index} -
+
- {parameter.name} + {parameter.name}
{/each}
@@ -715,7 +740,7 @@ @@ -940,14 +965,17 @@ top: 0; } - &.selected { - .primary { - background: rgba(255, 255, 255, 0.15); - } + &.node.selected .primary { + background: rgba(255, 255, 255, 0.15); + } - .parameters { - background: rgba(255, 255, 255, 0.1); - } + &.node.selected .parameters { + background: rgba(255, 255, 255, 0.1); + } + + &.layer.selected { + // This is the result of blending `rgba(255, 255, 255, 0.1)` over `rgba(0, 0, 0, 0.33)` + background: rgba(66, 66, 66, 0.4); } &.disabled { @@ -988,6 +1016,10 @@ &:first-of-type { margin-top: calc((24px - 8px) / 2); + + &:not(.primary-port) { + margin-top: calc((24px - 8px) / 2 + 24px); + } } &:last-of-type { @@ -1022,11 +1054,16 @@ .expanded .expand-arrow::after { transform: rotate(90deg); } + + .text-label { + overflow: hidden; + text-overflow: ellipsis; + } } .layer { border-radius: 8px; - min-width: 216px; + width: 216px; &::after { border: 1px solid var(--color-5-dullgray); @@ -1058,9 +1095,10 @@ pointer-events: none; position: absolute; margin: auto; - inset: 1px; - width: 100%; - height: 100%; + top: 1px; + left: 1px; + width: calc(100% - 2px); + height: calc(100% - 2px); } .port { @@ -1070,11 +1108,11 @@ right: 0; &.top { - top: -12px; + top: -9px; } &.bottom { - bottom: -12px; + bottom: -9px; } } } @@ -1099,7 +1137,7 @@ .node { flex-direction: column; border-radius: 2px; - min-width: 120px; + width: 120px; top: calc((var(--offset-top) + 0.5) * 24px); &::after { @@ -1122,10 +1160,12 @@ } .icon-label { + display: none; // Remove after we have unique icons for the nodes margin: 0 8px; } .text-label { + margin-left: 8px; // Remove after reenabling icon-label margin-right: 4px; } } @@ -1147,15 +1187,22 @@ border-radius: 0 0 2px 2px; } - .expand-arrow { - margin-left: 4px; - } - .text-label { width: 100%; + } - &.output { - text-align: right; + &.input { + .expand-arrow { + margin-left: 4px; + } + } + + &.output { + flex-direction: row-reverse; + text-align: right; + + .expand-arrow { + margin-right: 4px; } } }