전략편집기 수정
This commit is contained in:
@@ -29,6 +29,13 @@ import {
|
||||
type DefType,
|
||||
} from '../../utils/strategyEditorShared';
|
||||
import { buildSidewaysFilterNode } from '../../utils/sidewaysFilterPaletteStorage';
|
||||
import {
|
||||
isPaletteHtmlDrag,
|
||||
needsPointerPaletteDrag,
|
||||
readPaletteHtmlDragData,
|
||||
subscribePaletteDrag,
|
||||
type PaletteDragEvent,
|
||||
} from '../../utils/paletteDragSession';
|
||||
import { setStochPairSecondary } from '../../utils/stochOverboughtPair';
|
||||
import {
|
||||
setPriceExtremePairFilterLevel,
|
||||
@@ -1190,8 +1197,6 @@ function StrategyEditorCanvasInner({
|
||||
));
|
||||
}, [root, orphans, extraRoots, applyResolvedConnection, setEdges]);
|
||||
|
||||
const isPaletteDrag = (e: React.DragEvent) => e.dataTransfer.types.includes('application/json');
|
||||
|
||||
const resolvePaletteDrop = useCallback((flowPos: { x: number; y: number }) => {
|
||||
const hit = findNodeAtFlowPosition(flowPos, nodesRef.current);
|
||||
if (hit && isPaletteConnectTarget(hit.id, root, orphans)) {
|
||||
@@ -1200,24 +1205,63 @@ function StrategyEditorCanvasInner({
|
||||
return { mode: 'orphan' as const };
|
||||
}, [root, orphans]);
|
||||
|
||||
const isPaletteDrag = (e: React.DragEvent) => isPaletteHtmlDrag(e);
|
||||
|
||||
const applyPaletteDropAt = useCallback((
|
||||
data: { type: string; value: string; label: string; composite?: boolean },
|
||||
clientX: number,
|
||||
clientY: number,
|
||||
) => {
|
||||
const flowPos = screenToFlowPosition({ x: clientX, y: clientY });
|
||||
if (data.type === 'start') {
|
||||
addStartAt(flowPos);
|
||||
return;
|
||||
}
|
||||
const drop = resolvePaletteDrop(flowPos);
|
||||
if (drop.mode === 'connect') {
|
||||
applyDropWithAttach(drop.anchorId, data, flowPos);
|
||||
} else {
|
||||
addOrphanAt(data, flowPos);
|
||||
}
|
||||
}, [screenToFlowPosition, applyDropWithAttach, addOrphanAt, addStartAt, resolvePaletteDrop]);
|
||||
|
||||
const onPaneDrop = useCallback((e: React.DragEvent) => {
|
||||
e.preventDefault();
|
||||
clearDropPreview();
|
||||
try {
|
||||
const data = JSON.parse(e.dataTransfer.getData('application/json'));
|
||||
const flowPos = screenToFlowPosition({ x: e.clientX, y: e.clientY });
|
||||
if (data.type === 'start') {
|
||||
addStartAt(flowPos);
|
||||
const data = readPaletteHtmlDragData(e);
|
||||
if (!data) return;
|
||||
applyPaletteDropAt(data, e.clientX, e.clientY);
|
||||
}, [clearDropPreview, applyPaletteDropAt]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!needsPointerPaletteDrag()) return;
|
||||
return subscribePaletteDrag((ev: PaletteDragEvent) => {
|
||||
if (ev.phase === 'move') {
|
||||
const flowPos = screenToFlowPosition({ x: ev.x, y: ev.y });
|
||||
const drop = resolvePaletteDrop(flowPos);
|
||||
if (drop.mode === 'connect') {
|
||||
updateDropPreview(drop.anchorId, flowPos);
|
||||
} else {
|
||||
clearDropPreview();
|
||||
}
|
||||
return;
|
||||
}
|
||||
const drop = resolvePaletteDrop(flowPos);
|
||||
if (drop.mode === 'connect') {
|
||||
applyDropWithAttach(drop.anchorId, data, flowPos);
|
||||
} else {
|
||||
addOrphanAt(data, flowPos);
|
||||
if (ev.phase === 'end') {
|
||||
clearDropPreview();
|
||||
applyPaletteDropAt(ev.payload, ev.x, ev.y);
|
||||
return;
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
}, [clearDropPreview, screenToFlowPosition, applyDropWithAttach, addOrphanAt, addStartAt, resolvePaletteDrop]);
|
||||
if (ev.phase === 'cancel') {
|
||||
clearDropPreview();
|
||||
}
|
||||
});
|
||||
}, [
|
||||
screenToFlowPosition,
|
||||
resolvePaletteDrop,
|
||||
updateDropPreview,
|
||||
clearDropPreview,
|
||||
applyPaletteDropAt,
|
||||
]);
|
||||
|
||||
const onPaneDragOver = useCallback((e: React.DragEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
Reference in New Issue
Block a user