|
5 | 5 |
|
6 | 6 | import type { Editor } from "@graphite/editor";
|
7 | 7 | import type { Node } from "@graphite/messages.svelte";
|
8 |
| - import type { FrontendNode, FrontendGraphInput, FrontendGraphOutput } from "@graphite/messages.svelte"; |
| 8 | + import { type FrontendNode, type FrontendGraphInput, FrontendGraphOutput, } from "@graphite/messages.svelte"; |
9 | 9 | import type { NodeGraphState } from "@graphite/state-providers/node-graph";
|
10 | 10 | import type { IconName } from "@graphite/utility-functions/icons";
|
11 | 11 |
|
|
230 | 230 | $effect.pre(() => {
|
231 | 231 | nodeValues = Array.from($nodeGraph.nodes.values());
|
232 | 232 | });
|
| 233 | +
|
233 | 234 | // Key value is node id + input/output index
|
234 | 235 | // Imports/Export are stored at a key value of 0
|
235 | 236 |
|
|
340 | 341 | <!-- Import and Export ports -->
|
341 | 342 | <div class="imports-and-exports" style:transform-origin={`0 0`} style:transform={`translate(${$nodeGraph.transform.x}px, ${$nodeGraph.transform.y}px) scale(${$nodeGraph.transform.scale})`}>
|
342 | 343 | {#each $nodeGraph.imports as { outputMetadata, position }, index}
|
343 |
| - <svg |
344 |
| - xmlns="http://www.w3.org/2000/svg" |
345 |
| - viewBox="0 0 8 8" |
346 |
| - class="port" |
347 |
| - data-port="output" |
348 |
| - data-datatype={outputMetadata.dataType} |
349 |
| - style:--data-color={`var(--color-data-${outputMetadata.dataType.toLowerCase()})`} |
350 |
| - style:--data-color-dim={`var(--color-data-${outputMetadata.dataType.toLowerCase()}-dim)`} |
351 |
| - style:--offset-left={position.x / 24} |
352 |
| - style:--offset-top={position.y / 24} |
353 |
| - > |
354 |
| - <title>{`${dataTypeTooltip(outputMetadata)}\n\n${outputConnectedToText(outputMetadata)}`}</title> |
355 |
| - {#if outputMetadata.connectedTo !== undefined} |
356 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" /> |
357 |
| - {:else} |
358 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color-dim)" /> |
359 |
| - {/if} |
360 |
| - </svg> |
361 |
| - |
| 344 | + {@render port("port", "output", outputMetadata, position.x / 24, position.y / 24)} |
362 | 345 | <div
|
363 | 346 | class="edit-import-export import"
|
364 | 347 | onpointerenter={() => (hoveringImportIndex = index)}
|
|
414 | 397 | </div>
|
415 | 398 | {/if}
|
416 | 399 | {#each $nodeGraph.exports as { inputMetadata, position }, index}
|
417 |
| - <svg |
418 |
| - xmlns="http://www.w3.org/2000/svg" |
419 |
| - viewBox="0 0 8 8" |
420 |
| - class="port" |
421 |
| - data-port="input" |
422 |
| - data-datatype={inputMetadata.dataType} |
423 |
| - style:--data-color={`var(--color-data-${inputMetadata.dataType.toLowerCase()})`} |
424 |
| - style:--data-color-dim={`var(--color-data-${inputMetadata.dataType.toLowerCase()}-dim)`} |
425 |
| - style:--offset-left={position.x / 24} |
426 |
| - style:--offset-top={position.y / 24} |
427 |
| - > |
428 |
| - <title>{`${dataTypeTooltip(inputMetadata)}\n\n${inputConnectedToText(inputMetadata)}`}</title> |
429 |
| - {#if inputMetadata.connectedTo !== undefined} |
430 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" /> |
431 |
| - {:else} |
432 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color-dim)" /> |
433 |
| - {/if} |
434 |
| - </svg> |
| 400 | + {@render port("port", "input", inputMetadata, position.x / 24, position.y / 24)} |
435 | 401 | <div
|
436 | 402 | class="edit-import-export export"
|
437 | 403 | onpointerenter={() => (hoveringExportIndex = index)}
|
|
570 | 536 | <!-- Layer input port (from left) -->
|
571 | 537 | {#if node.exposedInputs.length > 0}
|
572 | 538 | <div class="input ports">
|
573 |
| - <svg |
574 |
| - xmlns="http://www.w3.org/2000/svg" |
575 |
| - viewBox="0 0 8 8" |
576 |
| - class="port" |
577 |
| - data-port="input" |
578 |
| - data-datatype={stackDataInput.dataType} |
579 |
| - style:--data-color={`var(--color-data-${stackDataInput.dataType.toLowerCase()})`} |
580 |
| - style:--data-color-dim={`var(--color-data-${stackDataInput.dataType.toLowerCase()}-dim)`} |
581 |
| - > |
582 |
| - <title>{`${dataTypeTooltip(stackDataInput)}\n\n${validTypesText(stackDataInput)}\n\n${inputConnectedToText(stackDataInput)}`}</title> |
583 |
| - {#if stackDataInput.connectedTo !== undefined} |
584 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" /> |
585 |
| - {:else} |
586 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color-dim)" /> |
587 |
| - {/if} |
588 |
| - </svg> |
| 539 | + {@render port("port", "input", stackDataInput)} |
589 | 540 | </div>
|
590 | 541 | {/if}
|
591 | 542 | <div class="details">
|
|
688 | 639 | <!-- Input ports -->
|
689 | 640 | <div class="input ports">
|
690 | 641 | {#if node.primaryInput?.dataType}
|
691 |
| - <svg |
692 |
| - xmlns="http://www.w3.org/2000/svg" |
693 |
| - viewBox="0 0 8 8" |
694 |
| - class="port primary-port" |
695 |
| - data-port="input" |
696 |
| - data-datatype={node.primaryInput?.dataType} |
697 |
| - style:--data-color={`var(--color-data-${node.primaryInput.dataType.toLowerCase()})`} |
698 |
| - style:--data-color-dim={`var(--color-data-${node.primaryInput.dataType.toLowerCase()}-dim)`} |
699 |
| - > |
700 |
| - <title>{`${dataTypeTooltip(node.primaryInput)}\n\n${validTypesText(node.primaryInput)}\n\n${inputConnectedToText(node.primaryInput)}`}</title> |
701 |
| - {#if node.primaryInput.connectedTo !== undefined} |
702 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" /> |
703 |
| - {:else} |
704 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color-dim)" /> |
705 |
| - {/if} |
706 |
| - </svg> |
| 642 | + {@render port("port primary-port", "input", node.primaryInput)} |
707 | 643 | {/if}
|
708 | 644 | {#each node.exposedInputs as secondary, index}
|
709 | 645 | {#if index < node.exposedInputs.length}
|
710 |
| - <svg |
711 |
| - xmlns="http://www.w3.org/2000/svg" |
712 |
| - viewBox="0 0 8 8" |
713 |
| - class="port" |
714 |
| - data-port="input" |
715 |
| - data-datatype={secondary.dataType} |
716 |
| - style:--data-color={`var(--color-data-${secondary.dataType.toLowerCase()})`} |
717 |
| - style:--data-color-dim={`var(--color-data-${secondary.dataType.toLowerCase()}-dim)`} |
718 |
| - > |
719 |
| - <title>{`${dataTypeTooltip(secondary)}\n\n${validTypesText(secondary)}\n\n${inputConnectedToText(secondary)}`}</title> |
720 |
| - {#if secondary.connectedTo !== undefined} |
721 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" /> |
722 |
| - {:else} |
723 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color-dim)" /> |
724 |
| - {/if} |
725 |
| - </svg> |
| 646 | + {@render port("port", "input", secondary)} |
726 | 647 | {/if}
|
727 | 648 | {/each}
|
728 | 649 | </div>
|
729 | 650 | <!-- Output ports -->
|
730 | 651 | <div class="output ports">
|
731 |
| - {#if node.primaryOutput} |
732 |
| - <svg |
733 |
| - xmlns="http://www.w3.org/2000/svg" |
734 |
| - viewBox="0 0 8 8" |
735 |
| - class="port primary-port" |
736 |
| - data-port="output" |
737 |
| - data-datatype={node.primaryOutput.dataType} |
738 |
| - style:--data-color={`var(--color-data-${node.primaryOutput.dataType.toLowerCase()})`} |
739 |
| - style:--data-color-dim={`var(--color-data-${node.primaryOutput.dataType.toLowerCase()}-dim)`} |
740 |
| - > |
741 |
| - <title>{`${dataTypeTooltip(node.primaryOutput)}\n\n${outputConnectedToText(node.primaryOutput)}`}</title> |
742 |
| - {#if node.primaryOutput.connectedTo !== undefined} |
743 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" /> |
744 |
| - {:else} |
745 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color-dim)" /> |
746 |
| - {/if} |
747 |
| - </svg> |
748 |
| - {/if} |
749 |
| - {#each node.exposedOutputs as secondary} |
750 |
| - <svg |
751 |
| - xmlns="http://www.w3.org/2000/svg" |
752 |
| - viewBox="0 0 8 8" |
753 |
| - class="port" |
754 |
| - data-port="output" |
755 |
| - data-datatype={secondary.dataType} |
756 |
| - style:--data-color={`var(--color-data-${secondary.dataType.toLowerCase()})`} |
757 |
| - style:--data-color-dim={`var(--color-data-${secondary.dataType.toLowerCase()}-dim)`} |
758 |
| - > |
759 |
| - <title>{`${dataTypeTooltip(secondary)}\n\n${outputConnectedToText(secondary)}`}</title> |
760 |
| - {#if secondary.connectedTo !== undefined} |
761 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" /> |
762 |
| - {:else} |
763 |
| - <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color-dim)" /> |
764 |
| - {/if} |
765 |
| - </svg> |
| 652 | + {@render port("port primary-port", "output", node.primaryOutput)} |
| 653 | + {#each node.exposedOutputs as secondary, outputIndex} |
| 654 | + {@render port("port", "output", secondary)} |
766 | 655 | {/each}
|
767 | 656 | </div>
|
768 | 657 | <svg class="border-mask" width="0" height="0">
|
|
792 | 681 | ></div>
|
793 | 682 | {/if}
|
794 | 683 |
|
| 684 | +{#snippet port(className: string, dataPort: string, node?: FrontendGraphInput | FrontendGraphOutput, offsetLeft?: number, offsetTop?: number)} |
| 685 | + {#if node} |
| 686 | + {@const color = node.dataType.toLowerCase()} |
| 687 | + <svg |
| 688 | + xmlns="http://www.w3.org/2000/svg" |
| 689 | + viewBox="0 0 8 8" |
| 690 | + class={className} |
| 691 | + data-port={dataPort} |
| 692 | + data-datatype={node.dataType} |
| 693 | + style:--data-color={`var(--color-data-${color})`} |
| 694 | + style:--data-color-dim={`var(--color-data-${color}-dim)`} |
| 695 | + style:--offset-left={offsetLeft} |
| 696 | + style:--offset-top={offsetTop} |
| 697 | + > |
| 698 | + {#if node instanceof FrontendGraphOutput} |
| 699 | + <title>{`${dataTypeTooltip(node)}\n\n${outputConnectedToText(node)}`}</title> |
| 700 | + {:else} |
| 701 | + <title>{`${dataTypeTooltip(node)}\n\n${validTypesText(node)}\n\n${inputConnectedToText(node)}`}</title> |
| 702 | + {/if} |
| 703 | + {#if node.connectedTo !== undefined} |
| 704 | + <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" /> |
| 705 | + {:else} |
| 706 | + <path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color-dim)" /> |
| 707 | + {/if} |
| 708 | + </svg> |
| 709 | + {/if} |
| 710 | +{/snippet} |
| 711 | + |
795 | 712 | <style lang="scss" global>
|
796 | 713 | .graph {
|
797 | 714 | position: relative;
|
|
0 commit comments