feat: add initial input prototypes
This commit is contained in:
parent
9b76299272
commit
19234bdac1
28
frontend/src/lib/components/NodeInput.svelte
Normal file
28
frontend/src/lib/components/NodeInput.svelte
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Checkbox from "$lib/elements/Checkbox.svelte";
|
||||||
|
import Float from "$lib/elements/Float.svelte";
|
||||||
|
import Integer from "$lib/elements/Integer.svelte";
|
||||||
|
import Select from "$lib/elements/Select.svelte";
|
||||||
|
import type { Node, NodeInput } from "$lib/types";
|
||||||
|
|
||||||
|
export let node: Node;
|
||||||
|
export let input: NodeInput;
|
||||||
|
export let id: string;
|
||||||
|
|
||||||
|
let value = node?.props?.[id] ?? input.value;
|
||||||
|
|
||||||
|
$: if (value) {
|
||||||
|
node.props = node.props || {};
|
||||||
|
node.props.value = value;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if input.type === "float"}
|
||||||
|
<Float bind:value />
|
||||||
|
{:else if input.type === "integer"}
|
||||||
|
<Integer bind:value />
|
||||||
|
{:else if input.type === "boolean"}
|
||||||
|
<Checkbox bind:value />
|
||||||
|
{:else if input.type === "select"}
|
||||||
|
<Select options={input.options} bind:value />
|
||||||
|
{/if}
|
@ -1,15 +1,22 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { NodeInput, Socket } from "$lib/types";
|
import type { NodeInput as NodeInputType, Socket } from "$lib/types";
|
||||||
import type { Node } from "$lib/types";
|
import type { Node } from "$lib/types";
|
||||||
import { getContext } from "svelte";
|
import { getContext } from "svelte";
|
||||||
import { createNodePath } from "$lib/helpers";
|
import { createNodePath } from "$lib/helpers";
|
||||||
import { possibleSocketIds } from "./graph/stores";
|
import { possibleSocketIds } from "./graph/stores";
|
||||||
|
import NodeInput from "./NodeInput.svelte";
|
||||||
|
import { getGraphManager } from "./graph/context";
|
||||||
|
|
||||||
export let node: Node;
|
export let node: Node;
|
||||||
export let input: NodeInput;
|
export let input: NodeInputType;
|
||||||
export let id: string;
|
export let id: string;
|
||||||
export let isLast = false;
|
export let isLast = false;
|
||||||
|
|
||||||
|
const socketId = `${node.id}-${id}`;
|
||||||
|
|
||||||
|
const graph = getGraphManager();
|
||||||
|
const inputSockets = graph.inputSockets;
|
||||||
|
|
||||||
const setDownSocket = getContext<(socket: Socket) => void>("setDownSocket");
|
const setDownSocket = getContext<(socket: Socket) => void>("setDownSocket");
|
||||||
const getSocketPosition =
|
const getSocketPosition =
|
||||||
getContext<(node: Node, index: string) => [number, number]>(
|
getContext<(node: Node, index: string) => [number, number]>(
|
||||||
@ -58,13 +65,12 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
class="wrapper"
|
class="wrapper"
|
||||||
class:disabled={$possibleSocketIds &&
|
class:disabled={$possibleSocketIds && !$possibleSocketIds.has(socketId)}
|
||||||
!$possibleSocketIds.has(`${node.id}-${id}`)}
|
|
||||||
>
|
>
|
||||||
<div class="content">
|
<div class="content" class:disabled={$inputSockets.has(socketId)}>
|
||||||
<label>{id}</label>
|
<label>{id}</label>
|
||||||
|
|
||||||
<div class="input">input</div>
|
<NodeInput {node} {input} {id} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if node.tmp?.type?.inputs?.[id].internal !== true}
|
{#if node.tmp?.type?.inputs?.[id].internal !== true}
|
||||||
@ -186,6 +192,11 @@
|
|||||||
/* fill: #161616; */
|
/* fill: #161616; */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content.disabled {
|
||||||
|
opacity: 0.2;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
.disabled svg path {
|
.disabled svg path {
|
||||||
d: var(--hover-path-disabled) !important;
|
d: var(--hover-path-disabled) !important;
|
||||||
/* fill: #060606 !important; */
|
/* fill: #060606 !important; */
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
{@const pos = getEdgePosition(edge)}
|
{@const pos = getEdgePosition(edge)}
|
||||||
{@const [x1, y1, x2, y2] = pos}
|
{@const [x1, y1, x2, y2] = pos}
|
||||||
<Edge
|
<Edge
|
||||||
color={$colors.backgroundColorLighter}
|
|
||||||
from={{
|
from={{
|
||||||
x: x1,
|
x: x1,
|
||||||
y: y1,
|
y: y1,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let checked: boolean;
|
export let value: boolean;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<input type="checkbox" bind:checked />
|
<input type="checkbox" bind:checked={value} />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
input[type="checkbox"] {
|
input[type="checkbox"] {
|
||||||
|
17
frontend/src/lib/elements/Float.story.svelte
Normal file
17
frontend/src/lib/elements/Float.story.svelte
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { Hst } from "@histoire/plugin-svelte";
|
||||||
|
export let Hst: Hst;
|
||||||
|
import Float from "./Float.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Hst.Story>
|
||||||
|
<div>
|
||||||
|
<Float value={0} min={0} max={6.9} />
|
||||||
|
</div>
|
||||||
|
</Hst.Story>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let value: number = 0;
|
||||||
|
export let min = 0;
|
||||||
|
export let max = 10;
|
||||||
|
export let step = 0.1;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<input type="number" bind:value {min} {max} {step} />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
input {
|
||||||
|
background: var(--background-color-lighter);
|
||||||
|
color: var(--text-color);
|
||||||
|
font-family: var(--font-family);
|
||||||
|
padding: 0.8em 1em;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
</style>
|
17
frontend/src/lib/elements/Integer.story.svelte
Normal file
17
frontend/src/lib/elements/Integer.story.svelte
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { Hst } from "@histoire/plugin-svelte";
|
||||||
|
export let Hst: Hst;
|
||||||
|
import Integer from "./Integer.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Hst.Story>
|
||||||
|
<div>
|
||||||
|
<Integer value={5} min={0} max={42} />
|
||||||
|
</div>
|
||||||
|
</Hst.Story>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,9 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let value: number = 0;
|
||||||
|
export let min = 0;
|
||||||
|
export let max = 10;
|
||||||
|
export let step = 1;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<input type="number" bind:value {min} {max} {step} />
|
||||||
|
|
17
frontend/src/lib/elements/Select.story.svelte
Normal file
17
frontend/src/lib/elements/Select.story.svelte
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { Hst } from "@histoire/plugin-svelte";
|
||||||
|
export let Hst: Hst;
|
||||||
|
import Select from "./Select.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Hst.Story>
|
||||||
|
<div>
|
||||||
|
<Select value={"banana"} options={["strawberry", "apple", "banana"]} />
|
||||||
|
</div>
|
||||||
|
</Hst.Story>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,21 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let options: string[] = [];
|
||||||
|
export let value: string = options[0];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<select bind:value>
|
||||||
|
{#each options as option}
|
||||||
|
<option value={option}>{option}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
select {
|
||||||
|
background: var(--background-color-lighter);
|
||||||
|
color: var(--text-color);
|
||||||
|
font-family: var(--font-family);
|
||||||
|
padding: 0.8em 1em;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
</style>
|
@ -6,7 +6,7 @@ const nodeTypes: NodeType[] = [
|
|||||||
{
|
{
|
||||||
id: "input/float",
|
id: "input/float",
|
||||||
inputs: {
|
inputs: {
|
||||||
"value": { type: "float" },
|
"value": { type: "float", value: 0.1 },
|
||||||
},
|
},
|
||||||
outputs: ["float"],
|
outputs: ["float"],
|
||||||
},
|
},
|
||||||
@ -14,8 +14,8 @@ const nodeTypes: NodeType[] = [
|
|||||||
id: "math",
|
id: "math",
|
||||||
inputs: {
|
inputs: {
|
||||||
"type": { type: "select", options: ["add", "subtract", "multiply", "divide"], internal: true },
|
"type": { type: "select", options: ["add", "subtract", "multiply", "divide"], internal: true },
|
||||||
"a": { type: "float" },
|
"a": { type: "float", value: 0.2 },
|
||||||
"b": { type: "float" },
|
"b": { type: "float", value: 0.2 },
|
||||||
},
|
},
|
||||||
outputs: ["float"],
|
outputs: ["float"],
|
||||||
},
|
},
|
||||||
@ -44,6 +44,8 @@ export class GraphManager {
|
|||||||
private _edges: Edge[] = [];
|
private _edges: Edge[] = [];
|
||||||
edges: Writable<Edge[]> = writable([]);
|
edges: Writable<Edge[]> = writable([]);
|
||||||
|
|
||||||
|
inputSockets: Writable<Set<string>> = writable(new Set());
|
||||||
|
|
||||||
history: HistoryManager = new HistoryManager(this);
|
history: HistoryManager = new HistoryManager(this);
|
||||||
|
|
||||||
private constructor(private graph: Graph, private nodeRegistry: NodeRegistry = new NodeRegistry()) {
|
private constructor(private graph: Graph, private nodeRegistry: NodeRegistry = new NodeRegistry()) {
|
||||||
@ -52,6 +54,11 @@ export class GraphManager {
|
|||||||
});
|
});
|
||||||
this.edges.subscribe((edges) => {
|
this.edges.subscribe((edges) => {
|
||||||
this._edges = edges;
|
this._edges = edges;
|
||||||
|
const s = new Set<string>();
|
||||||
|
for (const edge of edges) {
|
||||||
|
s.add(`${edge[2].id}-${edge[3]}`);
|
||||||
|
}
|
||||||
|
this.inputSockets.set(s);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ type NodeInputFloat = {
|
|||||||
value?: number;
|
value?: number;
|
||||||
min?: number;
|
min?: number;
|
||||||
max?: number;
|
max?: number;
|
||||||
|
step?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeInputInteger = {
|
type NodeInputInteger = {
|
||||||
@ -12,6 +13,11 @@ type NodeInputInteger = {
|
|||||||
max?: number;
|
max?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NodeInputBoolean = {
|
||||||
|
type: "boolean";
|
||||||
|
value?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
type NodeInputSelect = {
|
type NodeInputSelect = {
|
||||||
type: "select";
|
type: "select";
|
||||||
value?: string;
|
value?: string;
|
||||||
@ -22,4 +28,4 @@ type DefaultOptions = {
|
|||||||
internal?: boolean;
|
internal?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type NodeInput = (NodeInputFloat | NodeInputInteger | NodeInputSelect) & DefaultOptions;
|
export type NodeInput = (NodeInputBoolean | NodeInputFloat | NodeInputInteger | NodeInputSelect) & DefaultOptions;
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
font-family: 'Fira Code', monospace;
|
--font-family: 'Fira Code', monospace;
|
||||||
|
font-family: var(--font-family);
|
||||||
|
|
||||||
/* Spacing */
|
/* Spacing */
|
||||||
--spacing-xs: 4px;
|
--spacing-xs: 4px;
|
||||||
@ -48,6 +48,8 @@ body {
|
|||||||
--background-color: #151515;
|
--background-color: #151515;
|
||||||
--background-color-darker: #101010;
|
--background-color-darker: #101010;
|
||||||
--text-color: #aeaeae;
|
--text-color: #aeaeae;
|
||||||
|
|
||||||
|
background-color: var(--background-color-darker);
|
||||||
}
|
}
|
||||||
|
|
||||||
body.theme-catppuccin {
|
body.theme-catppuccin {
|
||||||
|
Loading…
Reference in New Issue
Block a user