From 6da190f06afae4717b434bdaf5ecb81734c1a2e9 Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Sat, 24 Aug 2024 11:43:39 +0800 Subject: [PATCH] allow for padding when drag selecting closes #481 --- interface/src/components/Graph/Graph.tsx | 9 +- packages/packages/src/list.ts | 436 +++++++++++------------ packages/runtime/src/utils/index.ts | 16 +- 3 files changed, 235 insertions(+), 226 deletions(-) diff --git a/interface/src/components/Graph/Graph.tsx b/interface/src/components/Graph/Graph.tsx index 9d934565..053458fd 100644 --- a/interface/src/components/Graph/Graph.tsx +++ b/interface/src/components/Graph/Graph.tsx @@ -29,6 +29,7 @@ import { toScreenSpace, } from "./Context"; import { Node } from "./Node"; +import { GRID_SIZE } from "./util"; type PanState = "none" | "waiting" | "active"; @@ -350,14 +351,18 @@ export const Graph = (props: Props) => { const items = [ ...[ - ...getNodesInRect(model().nodes.values(), rect, (node) => - interfaceCtx.nodeSizes.get(node), + ...getNodesInRect( + model().nodes.values(), + rect, + (node) => interfaceCtx.nodeSizes.get(node), + GRID_SIZE * 2, ), ].map((n) => ({ id: n.id, type: "node" as const })), ...[ ...getCommentBoxesInRect( model().commentBoxes.values(), rect, + GRID_SIZE * 2, ), ].map((b) => ({ id: b.id, diff --git a/packages/packages/src/list.ts b/packages/packages/src/list.ts index 7321edd2..da0f5ce0 100644 --- a/packages/packages/src/list.ts +++ b/packages/packages/src/list.ts @@ -3,222 +3,222 @@ import { Package } from "@macrograph/runtime"; import { t } from "@macrograph/typesystem"; export function pkg() { - const pkg = new Package({ - name: "List", - }); - - pkg.createSchema({ - name: "List Create", - type: "pure", - properties: { - number: { - name: "Entries", - type: t.int(), - default: 1, - }, - }, - createIO({ io, ctx, properties }) { - const value = ctx.getProperty(properties.number); - const w = io.wildcard(""); - const inputs = Array.from({ length: value }, (_, i) => ({ - value: io.dataInput({ - id: `value-${i}`, - type: t.wildcard(w), - }), - })); - - return { - inputs, - out: io.dataOutput({ - id: "", - type: t.list(t.wildcard(w)), - }), - }; - }, - run({ ctx, io }) { - const array = new Array(); - for (const input of io.inputs) { - array.push(ctx.getInput(input.value)); - } - - ctx.setOutput(io.out, array); - }, - }); - - pkg.createSchema({ - name: "Push List Value", - type: "exec", - createIO({ io }) { - const w = io.wildcard(""); - - return { - list: io.dataInput({ - id: "list", - type: t.list(t.wildcard(w)), - }), - value: io.dataInput({ - id: "value", - type: t.wildcard(w), - }), - }; - }, - run({ ctx, io }) { - ctx.getInput(io.list).push(ctx.getInput(io.value)); - }, - }); - - pkg.createSchema({ - name: "Insert List Value", - type: "exec", - createIO({ io }) { - const w = io.wildcard(""); - - return { - list: io.dataInput({ - id: "list", - type: t.list(t.wildcard(w)), - }), - index: io.dataInput({ - id: "index", - type: t.int(), - }), - value: io.dataInput({ - id: "value", - type: t.wildcard(w), - }), - }; - }, - run({ ctx, io }) { - ctx - .getInput(io.list) - .splice(ctx.getInput(io.index), 0, ctx.getInput(io.value)); - }, - }); - - pkg.createSchema({ - name: "Set List Value", - type: "exec", - createIO({ io }) { - const w = io.wildcard(""); - - return { - list: io.dataInput({ - id: "list", - type: t.list(t.wildcard(w)), - }), - index: io.dataInput({ - id: "index", - type: t.int(), - }), - value: io.dataInput({ - id: "value", - type: t.wildcard(w), - }), - }; - }, - run({ ctx, io }) { - ctx - .getInput(io.list) - .splice(ctx.getInput(io.index), 1, ctx.getInput(io.value)); - }, - }); - - pkg.createSchema({ - name: "Remove List Value", - type: "exec", - createIO({ io }) { - const w = io.wildcard(""); - - return { - list: io.dataInput({ - id: "list", - type: t.list(t.wildcard(w)), - }), - index: io.dataInput({ - id: "index", - type: t.int(), - }), - returnList: io.dataOutput({ - id: "returnList", - type: t.list(t.wildcard(w)), - }), - returnValue: io.dataOutput({ - id: "returnValue", - type: t.option(t.wildcard(w)), - }), - }; - }, - run({ ctx, io }) { - const list = [...ctx.getInput(io.list)]; - - const value = list.splice(ctx.getInput(io.index), 1)[0]; - - ctx.setOutput(io.returnList, list); - - ctx.setOutput(io.returnValue, Maybe(value)); - }, - }); - - pkg.createSchema({ - name: "Get List Value", - type: "pure", - createIO({ io }) { - const w = io.wildcard(""); - - return { - list: io.dataInput({ - id: "list", - type: t.list(t.wildcard(w)), - }), - index: io.dataInput({ - id: "index", - type: t.int(), - }), - return: io.dataOutput({ - id: "return", - name: "Value", - type: t.option(t.wildcard(w)), - }), - }; - }, - run({ ctx, io }) { - const array = ctx.getInput(io.list); - const index = ctx.getInput(io.index); - - ctx.setOutput( - io.return, - Maybe(array[index < 0 ? array.length + index : index]), - ); - }, - }); - - pkg.createSchema({ - name: "Join String List", - type: "pure", - createIO({ io }) { - return { - input: io.dataInput({ - id: "input", - type: t.list(t.string()), - }), - separator: io.dataInput({ - id: "separator", - name: "Separator", - type: t.string(), - }), - output: io.dataOutput({ - id: "output", - type: t.string(), - }), - }; - }, - run({ ctx, io }) { - ctx.setOutput( - io.output, - ctx.getInput(io.input).join(ctx.getInput(io.separator)), - ); - }, - }); - - return pkg; + const pkg = new Package({ + name: "List", + }); + + pkg.createSchema({ + name: "List Create", + type: "pure", + properties: { + number: { + name: "Entries", + type: t.int(), + default: 1, + }, + }, + createIO({ io, ctx, properties }) { + const value = ctx.getProperty(properties.number); + const w = io.wildcard(""); + const inputs = Array.from({ length: value }, (_, i) => ({ + value: io.dataInput({ + id: `value-${i}`, + type: t.wildcard(w), + }), + })); + + return { + inputs, + out: io.dataOutput({ + id: "", + type: t.list(t.wildcard(w)), + }), + }; + }, + run({ ctx, io }) { + const array = new Array(); + for (const input of io.inputs) { + array.push(ctx.getInput(input.value)); + } + + ctx.setOutput(io.out, array); + }, + }); + + pkg.createSchema({ + name: "Push List Value", + type: "exec", + createIO({ io }) { + const w = io.wildcard(""); + + return { + list: io.dataInput({ + id: "list", + type: t.list(t.wildcard(w)), + }), + value: io.dataInput({ + id: "value", + type: t.wildcard(w), + }), + }; + }, + run({ ctx, io }) { + ctx.getInput(io.list).push(ctx.getInput(io.value)); + }, + }); + + pkg.createSchema({ + name: "Insert List Value", + type: "exec", + createIO({ io }) { + const w = io.wildcard(""); + + return { + list: io.dataInput({ + id: "list", + type: t.list(t.wildcard(w)), + }), + index: io.dataInput({ + id: "index", + type: t.int(), + }), + value: io.dataInput({ + id: "value", + type: t.wildcard(w), + }), + }; + }, + run({ ctx, io }) { + ctx + .getInput(io.list) + .splice(ctx.getInput(io.index), 0, ctx.getInput(io.value)); + }, + }); + + pkg.createSchema({ + name: "Set List Value", + type: "exec", + createIO({ io }) { + const w = io.wildcard(""); + + return { + list: io.dataInput({ + id: "list", + type: t.list(t.wildcard(w)), + }), + index: io.dataInput({ + id: "index", + type: t.int(), + }), + value: io.dataInput({ + id: "value", + type: t.wildcard(w), + }), + }; + }, + run({ ctx, io }) { + ctx + .getInput(io.list) + .splice(ctx.getInput(io.index), 1, ctx.getInput(io.value)); + }, + }); + + pkg.createSchema({ + name: "Remove List Value", + type: "exec", + createIO({ io }) { + const w = io.wildcard(""); + + return { + list: io.dataInput({ + id: "list", + type: t.list(t.wildcard(w)), + }), + index: io.dataInput({ + id: "index", + type: t.int(), + }), + returnList: io.dataOutput({ + id: "returnList", + type: t.list(t.wildcard(w)), + }), + returnValue: io.dataOutput({ + id: "returnValue", + type: t.option(t.wildcard(w)), + }), + }; + }, + run({ ctx, io }) { + const list = [...ctx.getInput(io.list)]; + + const value = list.splice(ctx.getInput(io.index), 1)[0]; + + ctx.setOutput(io.returnList, list); + + ctx.setOutput(io.returnValue, Maybe(value)); + }, + }); + + pkg.createSchema({ + name: "Get List Value", + type: "pure", + createIO({ io }) { + const w = io.wildcard(""); + + return { + list: io.dataInput({ + id: "list", + type: t.list(t.wildcard(w)), + }), + index: io.dataInput({ + id: "index", + type: t.int(), + }), + return: io.dataOutput({ + id: "return", + name: "Value", + type: t.option(t.wildcard(w)), + }), + }; + }, + run({ ctx, io }) { + const array = ctx.getInput(io.list); + const index = ctx.getInput(io.index); + + ctx.setOutput( + io.return, + Maybe(array[index < 0 ? array.length + index : index]), + ); + }, + }); + + pkg.createSchema({ + name: "Join String List", + type: "pure", + createIO({ io }) { + return { + input: io.dataInput({ + id: "input", + type: t.list(t.string()), + }), + separator: io.dataInput({ + id: "separator", + name: "Separator", + type: t.string(), + }), + output: io.dataOutput({ + id: "output", + type: t.string(), + }), + }; + }, + run({ ctx, io }) { + ctx.setOutput( + io.output, + ctx.getInput(io.input).join(ctx.getInput(io.separator)), + ); + }, + }); + + return pkg; } diff --git a/packages/runtime/src/utils/index.ts b/packages/runtime/src/utils/index.ts index c06d7cef..c8a1e53a 100644 --- a/packages/runtime/src/utils/index.ts +++ b/packages/runtime/src/utils/index.ts @@ -58,20 +58,22 @@ export function getNodesInRect( nodes: IterableIterator, rect: DOMRect, getNodeSize: GetNodeSize, + padding = 0, ) { const ret = new Set(); for (const node of nodes) { const nodePosition = node.state.position; - if (nodePosition.x < rect.x || nodePosition.y < rect.y) continue; + if (nodePosition.x + padding < rect.x || nodePosition.y + padding < rect.y) + continue; const nodeSize = getNodeSize(node); if (!nodeSize) continue; if ( - nodePosition.x + nodeSize.width > rect.x + rect.width || - nodePosition.y + nodeSize.height > rect.y + rect.height + nodePosition.x + nodeSize.width - padding > rect.x + rect.width || + nodePosition.y + nodeSize.height - padding > rect.y + rect.height ) continue; @@ -84,17 +86,19 @@ export function getNodesInRect( export function getCommentBoxesInRect( boxes: IterableIterator, rect: DOMRect, + padding = 0, ) { const ret = new Set(); for (const box of boxes) { const position = box.position; - if (position.x < rect.x || position.y < rect.y) continue; + if (position.x + padding < rect.x || position.y + padding < rect.y) + continue; if ( - position.x + box.size.x > rect.x + rect.width || - position.y + box.size.y > rect.y + rect.height + position.x + box.size.x - padding > rect.x + rect.width || + position.y + box.size.y - padding > rect.y + rect.height ) continue;