diff --git a/src/pages/edit/Editor/renderer/ComponentPin/index.tsx b/src/pages/edit/Editor/renderer/ComponentPin/index.tsx
deleted file mode 100644
index a91daee..0000000
--- a/src/pages/edit/Editor/renderer/ComponentPin/index.tsx
+++ /dev/null
@@ -1,101 +0,0 @@
-import nullthrows from "nullthrows";
-import { theme } from "../../../../../common/theme";
-import type { CCNodePinId } from "../../../../../store/nodePin";
-import { useStore } from "../../../../../store/react";
-import { wrappingIncrementSimulationValue } from "../../../../../store/simulation";
-import { useComponentEditorStore } from "../../store";
-import { stringifySimulationValue } from "../../store/slices/core";
-import { getCCComponentEditorRendererNodeGeometry } from "./../Node/geometry";
-export type CCComponentEditorRendererComponentPinProps = {
- nodePinId: CCNodePinId;
-};
-export default function CCComponentEditorRendererComponentPin({
- nodePinId,
-}: CCComponentEditorRendererComponentPinProps) {
- const { store } = useStore();
- const componentEditorState = useComponentEditorStore()();
- const nodePin = nullthrows(store.nodePins.get(nodePinId));
- const interfaceComponentPin = nullthrows(
- store.componentPins.getByImplementation(nodePinId),
- );
- const type = interfaceComponentPin.type;
-
- const { label, onClick } =
- componentEditorState.editorMode === "edit"
- ? {
- label: interfaceComponentPin.name,
- onClick: null,
- }
- : {
- label: stringifySimulationValue(
- type === "input"
- ? nullthrows(
- componentEditorState.getInputValue({
- componentPinId: interfaceComponentPin.id,
- timeStep: componentEditorState.timeStep,
- }),
- )
- : nullthrows(componentEditorState.getNodePinValue(nodePinId)),
- ),
- onClick:
- type === "input"
- ? () => {
- const nodePinValue = nullthrows(
- componentEditorState.getInputValue({
- componentPinId: interfaceComponentPin.id,
- timeStep: componentEditorState.timeStep,
- }),
- );
- componentEditorState.setInputValue(
- {
- componentPinId: interfaceComponentPin.id,
- timeStep: componentEditorState.timeStep,
- },
- wrappingIncrementSimulationValue(nodePinValue),
- );
- }
- : null,
- };
-
- const nodePinPosition = nullthrows(
- getCCComponentEditorRendererNodeGeometry(
- store,
- nodePin.nodeId,
- ).nodePinPositionById.get(nodePinId),
- );
- const direction = type === "input" ? -1 : 1;
-
- return (
- <>
-
-
- {label}
-
- >
- );
-}
diff --git a/src/pages/edit/Editor/renderer/Node/components/Interface/geometry.ts b/src/pages/edit/Editor/renderer/Node/components/Interface/geometry.ts
new file mode 100644
index 0000000..bdc65b7
--- /dev/null
+++ b/src/pages/edit/Editor/renderer/Node/components/Interface/geometry.ts
@@ -0,0 +1,31 @@
+import { type Vector2, vector2 } from "../../../../../../../common/vector2";
+import type { CCNodePinId } from "../../../../../../../store/nodePin";
+import type {
+ CCComponentEditorRendererNodeLayout,
+ CCComponentEditorRendererNodeLayoutSource,
+} from "../../types";
+
+export const ccComponentEditorRendererNodeInterfaceLayoutConstants = {
+ width: 70,
+ height: 30,
+ labelWidth: 54,
+ labelHeight: 16,
+};
+
+export function ccComponentRendererNodeInterfaceLayoutCalculator(
+ source: CCComponentEditorRendererNodeLayoutSource,
+): CCComponentEditorRendererNodeLayout {
+ const { width, height } =
+ ccComponentEditorRendererNodeInterfaceLayoutConstants;
+ return {
+ size: vector2.create(width, height),
+ nodePinOffsetById: new Map([
+ ...source.inputNodePinIds.map(
+ (id) => [id, vector2.create(0, height / 2)] as const,
+ ),
+ ...source.outputNodePinIds.map(
+ (id) => [id, vector2.create(width, height / 2)] as const,
+ ),
+ ]),
+ };
+}
diff --git a/src/pages/edit/Editor/renderer/Node/components/Interface/index.tsx b/src/pages/edit/Editor/renderer/Node/components/Interface/index.tsx
new file mode 100644
index 0000000..d572fc4
--- /dev/null
+++ b/src/pages/edit/Editor/renderer/Node/components/Interface/index.tsx
@@ -0,0 +1,91 @@
+import nullthrows from "nullthrows";
+import { theme } from "../../../../../../../common/theme";
+import { useStore } from "../../../../../../../store/react";
+import { wrappingIncrementSimulationValue } from "../../../../../../../store/simulation";
+import { useComponentEditorStore } from "../../../../store";
+import { stringifySimulationValue } from "../../../../store/slices/core";
+import type { CCComponentEditorRendererNodeRendererProps } from "../../types";
+import { CCComponentEditorRendererNodeDefaultRenderer } from "../Default";
+import { ccComponentEditorRendererNodeInterfaceLayoutConstants as constants } from "./geometry";
+
+export function CCComponentEditorRendererNodeInterfaceRenderer(
+ props: CCComponentEditorRendererNodeRendererProps,
+) {
+ const { store } = useStore();
+ const editorState = useComponentEditorStore()();
+
+ const nodePin = nullthrows(
+ store.nodePins.getManyByNodeId(props.node.id)[0],
+ `Interface node ${props.node.id} is missing its pin`,
+ );
+ const componentPin = nullthrows(
+ store.componentPins.getByImplementation(nodePin.id),
+ );
+
+ const { label, onClick } =
+ editorState.editorMode === "edit"
+ ? { label: componentPin.name, onClick: null }
+ : componentPin.type === "input"
+ ? (() => {
+ const inputValueKey = {
+ componentPinId: componentPin.id,
+ timeStep: editorState.timeStep,
+ };
+ const value = nullthrows(editorState.getInputValue(inputValueKey));
+ return {
+ label: stringifySimulationValue(value),
+ onClick: () =>
+ editorState.setInputValue(
+ inputValueKey,
+ wrappingIncrementSimulationValue(value),
+ ),
+ };
+ })()
+ : {
+ label: stringifySimulationValue(
+ nullthrows(editorState.getNodePinValue(nodePin.id)),
+ ),
+ onClick: null,
+ };
+
+ const { width, height, labelWidth, labelHeight } = constants;
+
+ return (
+ <>
+
+ {
+ // Prevent the node from being selected or dragged
+ e.stopPropagation();
+ onClick();
+ },
+ style: { cursor: "pointer" },
+ }
+ : {})}
+ />
+
+ {label}
+
+ >
+ );
+}
diff --git a/src/pages/edit/Editor/renderer/Node/geometry.ts b/src/pages/edit/Editor/renderer/Node/geometry.ts
index 45c6853..2a29851 100644
--- a/src/pages/edit/Editor/renderer/Node/geometry.ts
+++ b/src/pages/edit/Editor/renderer/Node/geometry.ts
@@ -9,6 +9,7 @@ import type { CCNodeId } from "../../../../../store/node";
import { ccComponentRendererNodeConstLayoutCalculator } from "./components/Const/geometry";
import { ccComponentRendererNodeDefaultLayoutCalculator } from "./components/Default/geometry";
import { ccComponentRendererNodeDisplayLayoutCalculator } from "./components/Display/geometry";
+import { ccComponentRendererNodeInterfaceLayoutCalculator } from "./components/Interface/geometry";
import type {
CCComponentEditorRendererNodeGeometry,
CCComponentEditorRendererNodeLayout,
@@ -24,6 +25,10 @@ const specialLayoutCalculators: {
ccComponentRendererNodeDisplayLayoutCalculator,
[ccIntrinsicComponentTypes.CONST]:
ccComponentRendererNodeConstLayoutCalculator,
+ [ccIntrinsicComponentTypes.INPUT]:
+ ccComponentRendererNodeInterfaceLayoutCalculator,
+ [ccIntrinsicComponentTypes.OUTPUT]:
+ ccComponentRendererNodeInterfaceLayoutCalculator,
};
export function getCCComponentEditorRendererNodeLayout(
diff --git a/src/pages/edit/Editor/renderer/Node/index.tsx b/src/pages/edit/Editor/renderer/Node/index.tsx
index 9a09029..2926b85 100644
--- a/src/pages/edit/Editor/renderer/Node/index.tsx
+++ b/src/pages/edit/Editor/renderer/Node/index.tsx
@@ -13,6 +13,7 @@ import CCComponentEditorRendererNodePin from "../NodePin";
import { CCComponentEditorRendererNodeConstRenderer } from "./components/Const";
import { CCComponentEditorRendererNodeDefaultRenderer } from "./components/Default";
import { CCComponentEditorRendererNodeDisplayRenderer } from "./components/Display";
+import { CCComponentEditorRendererNodeInterfaceRenderer } from "./components/Interface";
import {
ccComponentEditorRendererLayoutToGeometry,
getCCComponentEditorRendererNodeLayout,
@@ -31,6 +32,10 @@ const specialRenderers: Partial<
[ccIntrinsicComponentTypes.DISPLAY]:
CCComponentEditorRendererNodeDisplayRenderer,
[ccIntrinsicComponentTypes.CONST]: CCComponentEditorRendererNodeConstRenderer,
+ [ccIntrinsicComponentTypes.INPUT]:
+ CCComponentEditorRendererNodeInterfaceRenderer,
+ [ccIntrinsicComponentTypes.OUTPUT]:
+ CCComponentEditorRendererNodeInterfaceRenderer,
};
export type CCComponentEditorRendererNodeProps = {
diff --git a/src/pages/edit/Editor/renderer/NodePin/index.tsx b/src/pages/edit/Editor/renderer/NodePin/index.tsx
index c1a5c98..433f526 100644
--- a/src/pages/edit/Editor/renderer/NodePin/index.tsx
+++ b/src/pages/edit/Editor/renderer/NodePin/index.tsx
@@ -9,7 +9,6 @@ import { input, output } from "../../../../../store/intrinsics/definitions";
import type { CCNodePinId } from "../../../../../store/nodePin";
import { useStore } from "../../../../../store/react";
import { useComponentEditorStore } from "../../store";
-import CCComponentEditorRendererComponentPin from "./../ComponentPin";
import {
CCComponentEditorRendererConnectionCore,
type CCComponentEditorRendererConnectionEndpoint,
@@ -146,14 +145,8 @@ export default function CCComponentEditorRendererNodePin({
},
});
- const interfaceComponentPin =
- store.componentPins.getByImplementation(nodePinId);
-
return (
<>
- {interfaceComponentPin && (
-
- )}