lingo3d
Version:
Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor
120 lines • 6.03 kB
JavaScript
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