replace ghost nodes by real nodes on drag end

This commit is contained in:
David Mosbach 2023-08-26 04:40:44 +02:00
parent 89c1d44141
commit 0e408faabc

View File

@ -428,6 +428,7 @@ var selection : WF.WFNode | WF.WFGhostNode | WF.WFEdge | null = null; // The cur
var rightSelection : WF.WFNode | WF.WFEdge | null = null; // The currently right clicked node/edge.
var edgeTo : WF.WFNode | null = null; // Target of an edge to be created.
var edgeFrom : WF.WFNode | null = null; // Start on an edge to be created.
var edgeTarget : WF.WFNode | null = null; // Possible source/target for an edge after dragging the respective ghost node.
//Utility elements
const curtain = <HTMLElement>document.getElementById('curtain');
const submenuBackdrop = <HTMLElement>document.getElementById('submenu-backdrop');
@ -572,14 +573,16 @@ export function addState() {
var nodeId = stateIdCounter ++;
var x = newStateCoords.x;
var y = newStateCoords.y;
var state : WF.WFNode = { id: 'state_' + nodeId,
x: x,
y: y,
name: 'state_' + nodeId,
fx: x,
fy: y,
val: 5,
stateData: new WF.StateData({ abbreviation: `S${nodeId}`, final: 'false' }) };
var state = new WF.WFNode ({
id: 'state_' + nodeId,
x: x,
y: y,
name: 'state_' + nodeId,
fx: x,
fy: y,
val: 5,
stateData: { abbreviation: `S${nodeId}`, final: 'false' }
});
workflow.states.push(state);
updateGraph();
select(state);
@ -587,8 +590,8 @@ export function addState() {
}
export function addEdge() {
var x = newStateCoords.x;
var y = newStateCoords.y;
var x = newStateCoords.x - 20;
var y = newStateCoords.y + 20;
var ghostState = new WF.WFGhostNode({
id: `@@ghost@(${x},${y})`,
x: x,
@ -596,11 +599,13 @@ export function addEdge() {
fx: x,
fy: y,
val: 7 });
var x = newStateCoords.x + 20;
var y = newStateCoords.y - 20;
var ghostState2 = new WF.WFGhostNode({
id: `@@ghost@(${x+50},${y})`,
x: x + 50,
id: `@@ghost@(${x},${y})`,
x: x,
y: y,
fx: x + 50,
fx: x,
fy: y,
val: 7 });
workflow.states.push(ghostState, ghostState2);
@ -712,14 +717,15 @@ function removeAction(action: WF.WFEdge) {
* Removes a state from the workflow.
* @param {*} state The state to remove.
*/
function removeState(state: WF.WFNode) {
function removeState(state: WF.WFNode | WF.WFGhostNode) {
workflow.actions
.filter(edge => edge.source === state || edge.target === state)
.forEach(edge => removeAction(edge));
workflow.states.splice(workflow.states.indexOf(state), 1);
var abbreviation = state.stateData && state.stateData.abbreviation;
abbreviation && stateAbbreviations.splice(stateAbbreviations.indexOf(abbreviation), 1);
nodeIndex.remove(state.id);
if (state instanceof WF.WFNode) {
stateAbbreviations.splice(stateAbbreviations.indexOf(state.stateData.abbreviation), 1);
nodeIndex.remove(state.id);
}
}
var selfLoops: Map<string, WF.WFEdge[]> = new Map(); // All edges whose targets equal their sources.
@ -1186,6 +1192,13 @@ function getEdgeColour(edge: LinkObject) {
ctx.lineWidth = 1;
ctx.stroke();
ctx.restore();
} else if (edgeTarget === node) {
ctx.save();
ctx.lineCap = 'round';
ctx.lineWidth = 2;
ctx.strokeStyle = nodeColourDefaultFinal.value();
ctx.stroke();
ctx.restore();
} else if (node === selection || node === rightSelection) {
ctx.save();
ctx.lineCap = 'round';
@ -1207,9 +1220,37 @@ function getEdgeColour(edge: LinkObject) {
ctx.fillText(wfNode.text, wfNode.x, wfNode.y);
}
})
.onNodeDrag((node: NodeObject, delta: { x: number, y: number }) => {
edgeTarget = null;
if (!(node instanceof WF.WFGhostNode)) return;
const fineTuningThreshold = 0;
if (Math.sqrt(Math.round(Math.abs(delta.x * delta.y))) > fineTuningThreshold) return;
for (const node2 of workflow.states) {
if (!(node2 instanceof WF.WFNode)) continue;
if (Math.sqrt(Math.pow(node.x - node2.x, 2) + Math.pow(node.y - node2.y, 2)) <= 2*node2.val) {
edgeTarget = node2;
break;
}
}
console.log('close:', edgeTarget);
})
.onNodeDragEnd((node: NodeObject) => {
node.fx = node.x;
node.fy = node.y;
if (node instanceof WF.WFGhostNode && edgeTarget) {
var edgesFrom : WF.WFEdge[] = [];
var edgesTo : WF.WFEdge[] = [];
workflow.actions.forEach(edge => {
edge.source === node && edgesFrom.push(edge);
edge.target === node && edgesTo.push(edge);
});
if (!(edgesFrom || edgesTo)) throw new Error('Could not find an edge for the dragged ghost node');
edgesFrom.forEach(edge => edge.source = <WF.WFNode>edgeTarget);
edgesTo.forEach(edge => edge.target = <WF.WFNode>edgeTarget);
removeState(node);
updateGraph();
}
})
.onNodeClick((node: NodeObject, _: MouseEvent) => {
const wfNode = node as (WF.WFNode | WF.WFGhostNode);