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 && ( - - )}