mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-25 23:08:13 +08:00
Update Imaginate to output bitmap data to the graph via Image Frame node (#1001)
* Multiple node outputs * Add new nodes * gcore use std by default to allow for testing * Allow multiple node outputs * Multiple outputs to frontend * Add ImageFrameNode to node registry * Minor cleanup * Basic transform implementation * Add some logging to image encoding * Fix ImageFrameNode * Add transform input to Imaginate node (#1014) * Add transform input to imaginate node * Force the resolution to be edited with no transform * Add transform to imaginate generation * Fix compilation --------- Co-authored-by: Keavon Chambers <keavon@keavon.com> * Add labels to node outputs * Fix seed; disable mask when transform is disconnected; add Imaginate tooltips * Rename 'Input Multiple' node to 'Input' * Code review * Replicate to Svelte * Show only the primary input chain in the Properties panel --------- Co-authored-by: Dennis Kobert <dennis@kobert.dev> Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
Dennis Kobert
parent
70f4d60e66
commit
e14618b234
@@ -92,12 +92,15 @@
|
||||
}
|
||||
|
||||
function resolveLink(link: FrontendNodeLink, containerBounds: HTMLDivElement): { nodePrimaryOutput: HTMLDivElement | undefined; nodePrimaryInput: HTMLDivElement | undefined } {
|
||||
const connectorIndex = Number(link.linkEndInputIndex);
|
||||
const outputIndex = Number(link.linkStartOutputIndex);
|
||||
const inputIndex = Number(link.linkEndInputIndex);
|
||||
|
||||
const nodePrimaryOutput = (containerBounds.querySelector(`[data-node="${String(link.linkStart)}"] [data-port="output"]`) || undefined) as HTMLDivElement | undefined;
|
||||
const nodeOutputConnectors = containerBounds.querySelectorAll(`[data-node="${String(link.linkStart)}"] [data-port="output"]`) || undefined;
|
||||
|
||||
const nodeInputConnectors = containerBounds.querySelectorAll(`[data-node="${String(link.linkEnd)}"] [data-port="input"]`) || undefined;
|
||||
const nodePrimaryInput = nodeInputConnectors?.[connectorIndex] as HTMLDivElement | undefined;
|
||||
|
||||
const nodePrimaryOutput = nodeOutputConnectors?.[outputIndex] as HTMLDivElement | undefined;
|
||||
const nodePrimaryInput = nodeInputConnectors?.[inputIndex] as HTMLDivElement | undefined;
|
||||
return { nodePrimaryOutput, nodePrimaryInput };
|
||||
}
|
||||
|
||||
@@ -263,8 +266,8 @@
|
||||
const inputIndexInt = BigInt(inputIndex);
|
||||
const links = $nodeGraph.links;
|
||||
const linkIndex = links.findIndex((value) => value.linkEnd === nodeIdInt && value.linkEndInputIndex === inputIndexInt);
|
||||
const queryString = `[data-node="${String(links[linkIndex].linkStart)}"] [data-port="output"]`;
|
||||
linkInProgressFromConnector = (nodesContainer.querySelector(queryString) || undefined) as HTMLDivElement | undefined;
|
||||
const nodeOutputConnectors = nodesContainer.querySelectorAll(`[data-node="${String(links[linkIndex].linkStart)}"] [data-port="output"]`) || undefined;
|
||||
linkInProgressFromConnector = nodeOutputConnectors?.[Number(links[linkIndex].linkEndInputIndex)] as HTMLDivElement | undefined;
|
||||
const nodeInputConnectors = nodesContainer.querySelectorAll(`[data-node="${String(links[linkIndex].linkEnd)}"] [data-port="input"]`) || undefined;
|
||||
linkInProgressToConnector = nodeInputConnectors?.[Number(links[linkIndex].linkEndInputIndex)] as HTMLDivElement | undefined;
|
||||
disconnecting = { nodeId: nodeIdInt, inputIndex, linkIndex };
|
||||
@@ -359,13 +362,16 @@
|
||||
|
||||
if (outputNode && inputNode && outputConnectedNodeID && inputConnectedNodeID) {
|
||||
const inputNodeInPorts = Array.from(inputNode.querySelectorAll(`[data-port="input"]`));
|
||||
const outputNodeInPorts = Array.from(outputNode.querySelectorAll(`[data-port="output"]`));
|
||||
|
||||
const inputNodeConnectionIndexSearch = inputNodeInPorts.indexOf(linkInProgressToConnector);
|
||||
const outputNodeConnectionIndexSearch = outputNodeInPorts.indexOf(linkInProgressFromConnector);
|
||||
|
||||
const inputNodeConnectionIndex = inputNodeConnectionIndexSearch > -1 ? inputNodeConnectionIndexSearch : undefined;
|
||||
const outputNodeConnectionIndex = outputNodeConnectionIndexSearch > -1 ? outputNodeConnectionIndexSearch : undefined;
|
||||
|
||||
if (inputNodeConnectionIndex !== undefined) {
|
||||
// const oneBasedIndex = inputNodeConnectionIndex + 1;
|
||||
|
||||
editor.instance.connectNodesByLink(BigInt(outputConnectedNodeID), BigInt(inputConnectedNodeID), inputNodeConnectionIndex);
|
||||
if (inputNodeConnectionIndex !== undefined && outputNodeConnectionIndex !== undefined) {
|
||||
editor.instance.connectNodesByLink(BigInt(outputConnectedNodeID), outputNodeConnectionIndex, BigInt(inputConnectedNodeID), inputNodeConnectionIndex);
|
||||
}
|
||||
}
|
||||
} else if (draggingNodes) {
|
||||
@@ -411,8 +417,8 @@
|
||||
});
|
||||
// If the node has been dragged on top of the link then connect it into the middle.
|
||||
if (link) {
|
||||
editor.instance.connectNodesByLink(link.linkStart, selectedNodeId, 0);
|
||||
editor.instance.connectNodesByLink(selectedNodeId, link.linkEnd, Number(link.linkEndInputIndex));
|
||||
editor.instance.connectNodesByLink(link.linkStart, 0, selectedNodeId, 0);
|
||||
editor.instance.connectNodesByLink(selectedNodeId, 0, link.linkEnd, Number(link.linkEndInputIndex));
|
||||
editor.instance.shiftNode(selectedNodeId);
|
||||
}
|
||||
}
|
||||
@@ -482,10 +488,11 @@
|
||||
{/if}
|
||||
<div class="nodes" style:transform={`scale(${transform.scale}) translate(${transform.x}px, ${transform.y}px)`} style:transform-origin={`0 0`} bind:this={nodesContainer}>
|
||||
{#each $nodeGraph.nodes as node (String(node.id))}
|
||||
{@const exposedInputsOutputs = [...node.exposedInputs, ...node.outputs.slice(1)]}
|
||||
<div
|
||||
class="node"
|
||||
class:selected={selected.includes(node.id)}
|
||||
class:output={node.output}
|
||||
class:previewed={node.previewed}
|
||||
class:disabled={node.disabled}
|
||||
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)}
|
||||
@@ -508,9 +515,9 @@
|
||||
<div
|
||||
class="output port"
|
||||
data-port="output"
|
||||
data-datatype={node.outputs[0]}
|
||||
style:--data-color={`var(--color-data-${node.outputs[0]})`}
|
||||
style:--data-color-dim={`var(--color-data-${node.outputs[0]}-dim)`}
|
||||
data-datatype={node.outputs[0].dataType}
|
||||
style:--data-color={`var(--color-data-${node.outputs[0].dataType})`}
|
||||
style:--data-color-dim={`var(--color-data-${node.outputs[0].dataType}-dim)`}
|
||||
>
|
||||
<div />
|
||||
</div>
|
||||
@@ -519,22 +526,34 @@
|
||||
<IconLabel icon={nodeIcon(node.displayName)} />
|
||||
<TextLabel>{node.displayName}</TextLabel>
|
||||
</div>
|
||||
{#if node.exposedInputs.length > 0}
|
||||
<div class="arguments">
|
||||
{#each node.exposedInputs as argument, index (index)}
|
||||
<div class="argument">
|
||||
{#if exposedInputsOutputs.length > 0}
|
||||
<div class="parameters">
|
||||
{#each exposedInputsOutputs as parameter, index (index)}
|
||||
<div class="parameter">
|
||||
<div class="ports">
|
||||
<div
|
||||
class="input port"
|
||||
data-port="input"
|
||||
data-datatype={argument.dataType}
|
||||
style:--data-color={`var(--color-data-${argument.dataType})`}
|
||||
style:--data-color-dim={`var(--color-data-${argument.dataType}-dim)`}
|
||||
>
|
||||
<div />
|
||||
</div>
|
||||
{#if index < node.exposedInputs.length}
|
||||
<div
|
||||
class="input port"
|
||||
data-port="input"
|
||||
data-datatype={parameter.dataType}
|
||||
style:--data-color={`var(--color-data-${parameter.dataType})`}
|
||||
style:--data-color-dim={`var(--color-data-${parameter.dataType}-dim)`}
|
||||
>
|
||||
<div />
|
||||
</div>
|
||||
{:else}
|
||||
<div
|
||||
class="output port"
|
||||
data-port="output"
|
||||
data-datatype={parameter.dataType}
|
||||
style:--data-color={`var(--color-data-${parameter.dataType})`}
|
||||
style:--data-color-dim={`var(--color-data-${parameter.dataType}-dim)`}
|
||||
>
|
||||
<div />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<TextLabel>{argument.name}</TextLabel>
|
||||
<TextLabel class={index < node.exposedInputs.length ? "name" : "output"}>{parameter.name}</TextLabel>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
@@ -656,7 +675,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.output {
|
||||
&.previewed {
|
||||
outline: 3px solid var(--color-data-vector);
|
||||
}
|
||||
|
||||
@@ -679,20 +698,28 @@
|
||||
}
|
||||
}
|
||||
|
||||
.arguments {
|
||||
.parameters {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
.argument {
|
||||
.parameter {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 24px;
|
||||
width: 100%;
|
||||
width: calc(100% - 24px * 2);
|
||||
margin-left: 24px;
|
||||
margin-right: 24px;
|
||||
|
||||
.text-label {
|
||||
width: 100%;
|
||||
|
||||
&.output {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Squares to cover up the rounded corners of the primary area and make them have a straight edge
|
||||
|
||||
@@ -83,6 +83,12 @@ export class NodeGraphInput {
|
||||
readonly name!: string;
|
||||
}
|
||||
|
||||
export class NodeGraphOutput {
|
||||
readonly dataType!: FrontendGraphDataType;
|
||||
|
||||
readonly name!: string;
|
||||
}
|
||||
|
||||
export class FrontendNode {
|
||||
readonly id!: bigint;
|
||||
|
||||
@@ -92,12 +98,12 @@ export class FrontendNode {
|
||||
|
||||
readonly exposedInputs!: NodeGraphInput[];
|
||||
|
||||
readonly outputs!: FrontendGraphDataType[];
|
||||
readonly outputs!: NodeGraphOutput[];
|
||||
|
||||
@TupleToVec2
|
||||
readonly position!: XY | undefined;
|
||||
|
||||
readonly output!: boolean;
|
||||
readonly previewed!: boolean;
|
||||
|
||||
readonly disabled!: boolean;
|
||||
}
|
||||
@@ -105,6 +111,8 @@ export class FrontendNode {
|
||||
export class FrontendNodeLink {
|
||||
readonly linkStart!: bigint;
|
||||
|
||||
readonly linkStartOutputIndex!: bigint;
|
||||
|
||||
readonly linkEnd!: bigint;
|
||||
|
||||
readonly linkEndInputIndex!: bigint;
|
||||
|
||||
Reference in New Issue
Block a user