UNPKG

lingo3d

Version:

Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor

120 lines 6.03 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "preact/jsx-runtime"; import { event } from "@lincode/events"; import { Point } from "@lincode/math"; import { memo } from "preact/compat"; import { useEffect, useMemo, useState } from "preact/hooks"; import { emitSelectionTarget } from "../../events/onSelectionTarget"; import { EDITOR_WIDTH } from "../../globals"; import { getGameGraph } from "../../states/useGameGraph"; import { getSelectionTarget } from "../../states/useSelectionTarget"; import SpawnNode from "../../visualScripting/SpawnNode"; import { getIncludeKeys } from "../../visualScripting/utils/getIncludeKeys"; import { initConnectorIn } from "../Editor/addInputs"; import addTargetInputs from "../Editor/addTargetInputs"; import { getOriginalInstance } from "../Editor/createParams"; import usePane from "../Editor/usePane"; import mergeRefs from "../hooks/mergeRefs"; import usePan from "../hooks/usePan"; import useSyncState from "../hooks/useSyncState"; import getDisplayName from "../utils/getDisplayName"; import { stopPropagation } from "../utils/stopPropagation"; import Bezier from "./Bezier"; import GearIcon from "./icons/GearIcon"; import { nodeContexMenuSignal } from "./NodeContextMenu"; import { getStagePosition, zoomSignal } from "./Stage/stageSignals"; import convertToTemplateNodes from "./utils/convertToTemplateNodes"; import createConnector from "./utils/createConnector"; import { uuidMap } from "../../collections/idCollections"; import { draggingItemPtr } from "../../pointers/draggingItemPtr"; let panningUUID; export const [emitNodeMove, onNodeMove] = event(); const Node = memo(({ uuid, data, onEdit }) => { const manager = useMemo(() => uuidMap.get(uuid), []); const displayName = useMemo(() => getDisplayName(manager), []); const pressRef = usePan({ onPan: (e) => { getGameGraph().mergeData({ [uuid]: { type: "node", x: data.x + e.deltaX / zoomSignal.value, y: data.y + e.deltaY / zoomSignal.value } }); emitNodeMove(uuid); }, onPanStart: () => { panningUUID = uuid; emitSelectionTarget(manager, true); }, onPanEnd: () => (panningUUID = undefined) }); const [pane, setContainer] = usePane(); const [bezierStart, setBezierStart] = useState(); const [bezierEnd, setBezierEnd] = useState(); const [refresh, setRefresh] = useState({}); const selectionTarget = useSyncState(getSelectionTarget); const [initConnector, onDrop] = useMemo(() => { const onDrop = (_, draggingItem, prop) => { if (getOriginalInstance(draggingItem.manager) instanceof SpawnNode) { createConnector(draggingItem.manager, draggingItem.prop, convertToTemplateNodes(manager, draggingItem.manager), prop, draggingItem.xyz); return; } createConnector(draggingItem.manager, draggingItem.prop, manager, prop, draggingItem.xyz); }; const initConnector = (el) => el && initConnectorIn(el, "uuid", { onDrop }); return [initConnector, onDrop]; }, []); useEffect(() => { if (!pane) return; const handle0 = addTargetInputs(pane, manager, getIncludeKeys(manager), { onDragStart: (e) => setBezierStart(getStagePosition(e.clientX, e.clientY)), onDrag: (e) => setBezierEnd(getStagePosition(e.clientX, e.clientY)), onDragEnd: () => { setBezierStart(undefined); setBezierEnd(undefined); }, onDrop }); const handle1 = manager.$events.on("runtimeSchema", () => setRefresh({})); return () => { handle0.cancel(); handle1.cancel(); }; }, [pane, refresh]); const handleContextMenu = (e) => { nodeContexMenuSignal.value = new Point(e.clientX, e.clientY); emitSelectionTarget(manager, true); }; return (_jsxs(_Fragment, { children: [_jsxs("div", { style: { width: EDITOR_WIDTH + 10, position: "absolute", left: data.x, top: data.y, outline: selectionTarget === manager ? "1px solid white" : undefined }, children: [_jsxs("div", { style: { fontSize: 16, marginTop: -24, display: "flex", alignItems: "center" }, children: [_jsx("div", { className: "lingo3d-flexcenter lingo3d-connector", id: manager.uuid + " uuid in", ref: initConnector, children: _jsx("div", { className: "lingo3d-connector-child", style: { border: "1px solid white" } }) }), _jsx("div", { style: { zIndex: 1 }, ref: pressRef, onContextMenu: handleContextMenu, children: displayName }), _jsx("div", { className: "lingo3d-flexcenter", style: { padding: 4, margin: 4, background: "rgba(255, 255, 255, 0.1)", zIndex: 1, cursor: "pointer" }, onClick: onEdit && manager ? () => onEdit(manager) : undefined, children: _jsx(GearIcon, {}) })] }), _jsx("div", { ref: mergeRefs(setContainer, stopPropagation), style: { width: "100%" }, onMouseDown: () => emitSelectionTarget(manager, true), onContextMenu: handleContextMenu })] }), _jsx(Bezier, { start: bezierStart, end: bezierEnd })] })); }, (prev) => { if (prev.uuid === panningUUID) return false; if (!draggingItemPtr[0]) return true; return draggingItemPtr[0].uuid !== prev.uuid; }); export default Node; //# sourceMappingURL=Node.js.map