Skip to content

Commit

Permalink
Merge branch 'main' into safari_palette_display
Browse files Browse the repository at this point in the history
  • Loading branch information
tomlyn authored Dec 17, 2024
2 parents ceeb22f + cac0859 commit 1014e44
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,13 @@ export default class CanvasUtils {
return null;
}

// Returns the distance from the start point to finsih point of the link line.
// Returns true if point 1 is inside a circle of the specified radius whose
// center is point 2.
static isInside(point1, point2, radius) {
return Math.sqrt(Math.pow(point1.x - point2.x, 2) + Math.pow(point1.y - point2.y, 2)) < radius;
}

// Returns the distance from the start point to finish point of the link line.
static getLinkDistance(link) {
const x = link.x2 - link.x1;
const y = link.y2 - link.y1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ export const PORT_DISPLAY_JSX = "jsx";
export const FLOW_IN = "in";
export const FLOW_OUT = "out";

export const SINGLE_CLICK = "SINGLE_CLICK";
export const SINGLE_CLICK_CONTEXTMENU = "SINGLE_CLICK_CONTEXTMENU";
export const DOUBLE_CLICK = "DOUBLE_CLICK";

// Variations of association links - when enableAssocLinkType === ASSOC_RIGHT_SIDE_CURVE
export const ASSOC_VAR_CURVE_RIGHT = "curveRight";
export const ASSOC_VAR_CURVE_LEFT = "curveLeft";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { ASSOC_RIGHT_SIDE_CURVE, ASSOCIATION_LINK, NODE_LINK, COMMENT_LINK,
WYSIWYG, CAUSE_KEYBOARD, CAUSE_MOUSE,
FLOW_IN, FLOW_OUT,
PORT_WIDTH_DEFAULT, PORT_HEIGHT_DEFAULT,
SINGLE_CLICK, SINGLE_CLICK_CONTEXTMENU, DOUBLE_CLICK,
CANVAS_FOCUS
} from "./constants/canvas-constants";
import SUPERNODE_ICON from "../../assets/images/supernode.svg";
Expand Down Expand Up @@ -1347,15 +1348,15 @@ export default class SVGCanvasRenderer {
this.logger.log("Canvas - click-zoom");

this.canvasController.clickActionHandler({
clickType: d3Event.type === "contextmenu" ? "SINGLE_CLICK_CONTEXTMENU" : "SINGLE_CLICK",
clickType: d3Event.type === "contextmenu" ? SINGLE_CLICK_CONTEXTMENU : SINGLE_CLICK,
objectType: "canvas",
selectedObjectIds: this.activePipeline.getSelectedObjectIds()
});
})
.on("dblclick.zoom", () => {
this.logger.log("Zoom - double click");
this.canvasController.clickActionHandler({
clickType: "DOUBLE_CLICK",
clickType: DOUBLE_CLICK,
objectType: "canvas",
selectedObjectIds: this.activePipeline.getSelectedObjectIds() });
})
Expand Down Expand Up @@ -2276,7 +2277,7 @@ export default class SVGCanvasRenderer {
this.logger.log("Node Group - double click");
CanvasUtils.stopPropagationAndPreventDefault(d3Event);
this.canvasController.clickActionHandler({
clickType: "DOUBLE_CLICK",
clickType: DOUBLE_CLICK,
objectType: "node",
id: d.id,
selectedObjectIds: this.activePipeline.getSelectedObjectIds(),
Expand Down Expand Up @@ -2579,7 +2580,7 @@ export default class SVGCanvasRenderer {
// TODO - Issue 2465 - Find out why this problem occurs.
if (objectType === "node" || objectType === "link") {
this.canvasController.clickActionHandler({
clickType: d3EventType === "contextmenu" || this.ellipsisClicked ? "SINGLE_CLICK_CONTEXTMENU" : "SINGLE_CLICK",
clickType: d3EventType === "contextmenu" || this.ellipsisClicked ? SINGLE_CLICK_CONTEXTMENU : SINGLE_CLICK,
objectType: objectType,
id: d.id,
selectedObjectIds: this.activePipeline.getSelectedObjectIds(),
Expand Down Expand Up @@ -4189,7 +4190,7 @@ export default class SVGCanvasRenderer {
this.displayCommentTextArea(d, d3Event.currentTarget);

this.canvasController.clickActionHandler({
clickType: "DOUBLE_CLICK",
clickType: DOUBLE_CLICK,
objectType: "comment",
id: d.id,
selectedObjectIds: this.activePipeline.getSelectedObjectIds(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ import { ASSOCIATION_LINK, COMMENT_LINK, NODE_LINK,
LINK_TYPE_CURVE, LINK_TYPE_STRAIGHT, LINK_SELECTION_DETACHABLE,
FLOW_IN, FLOW_OUT,
PORT_DISPLAY_CIRCLE,
LINK_METHOD_PORTS }
from "./constants/canvas-constants.js";
LINK_METHOD_PORTS,
SINGLE_CLICK
} from "./constants/canvas-constants.js";

// This utility files provides a drag handler which manages drag operations to
// create new links either between nodes or from a comment to a node.
Expand Down Expand Up @@ -65,14 +66,14 @@ export default class SVGCanvasUtilsDragNewLink {
dragStartNewLink(d3Event, d) {
if (this.isEventForOutputPort(d3Event)) {
const node = this.getNodeForPort(d3Event);
this.startOutputPortNewLink(d, node);
this.startOutputPortNewLink(d3Event, d, node);

} else if (this.isEventForInputPort(d3Event)) {
const node = this.getNodeForPort(d3Event);
this.startInputPortNewLink(d, node);
this.startInputPortNewLink(d3Event, d, node);

} else if (this.ren.activePipeline.getObjectTypeName(d) === "comment") {
this.startCommentNewLink(d);
this.startCommentNewLink(d3Event, d);
}
}

Expand Down Expand Up @@ -110,7 +111,7 @@ export default class SVGCanvasUtilsDragNewLink {
}

// Initialize this.drawingNewLinkData when dragging a comment port.
startCommentNewLink(comment) {
startCommentNewLink(d3Event, comment) {
const srcObj = this.ren.activePipeline.getComment(comment.id);
this.drawingNewLinkData = {
srcObj: srcObj,
Expand All @@ -119,20 +120,22 @@ export default class SVGCanvasUtilsDragNewLink {
x: comment.x_pos - this.ren.canvasLayout.commentHighlightGap,
y: comment.y_pos - this.ren.canvasLayout.commentHighlightGap
},
mousePos: { x: d3Event.x, y: d3Event.y },
linkArray: []
};
}

// Initialize this.drawingNewLinkData when dragging an input port. This gesture
// is only supported for association link creation.
startInputPortNewLink(port, node) {
startInputPortNewLink(d3Event, port, node) {
if (this.ren.config.enableAssocLinkCreation) {
const srcNode = this.ren.activePipeline.getNode(node.id);
const portIndex = CanvasUtils.getPortIndex(node.inputs, port.id);
this.drawingNewLinkData = {
srcObj: srcNode,
srcPort: port,
action: this.ren.config.enableAssocLinkCreation ? ASSOCIATION_LINK : NODE_LINK,
mousePos: { x: d3Event.x, y: d3Event.y },
startPos: { x: srcNode.x_pos + port.cx, y: srcNode.y_pos + port.cy },
portFlow: FLOW_IN,
portDisplayInfo: this.ren.getPortDisplayInfo(srcNode.layout.inputPortDisplayObjects, portIndex),
Expand All @@ -145,14 +148,15 @@ export default class SVGCanvasUtilsDragNewLink {
}

// Initialize this.drawingNewLinkData when dragging an output port.
startOutputPortNewLink(port, node) {
startOutputPortNewLink(d3Event, port, node) {
const srcNode = this.ren.activePipeline.getNode(node.id);
if (!CanvasUtils.isSrcCardinalityAtMax(port.id, srcNode, this.ren.activePipeline.links)) {
const portIndex = CanvasUtils.getPortIndex(node.outputs, port.id);
this.drawingNewLinkData = {
srcObj: srcNode,
srcPort: port,
action: this.ren.config.enableAssocLinkCreation ? ASSOCIATION_LINK : NODE_LINK,
mousePos: { x: d3Event.x, y: d3Event.y },
startPos: { x: srcNode.x_pos + port.cx, y: srcNode.y_pos + port.cy },
portFlow: FLOW_OUT,
portDisplayInfo: this.ren.getPortDisplayInfo(srcNode.layout.outputPortDisplayObjects, portIndex),
Expand Down Expand Up @@ -348,6 +352,21 @@ export default class SVGCanvasUtilsDragNewLink {
const drawingNewLinkData = this.drawingNewLinkData;
this.drawingNewLinkData = null;

// If the user has not dragged the mouse far enough to create a new link, we
// treat it as a click on the port.
if (this.isClicked(drawingNewLinkData.mousePos, d3Event)) {
this.removeNewLink();
this.ren.canvasController.clickActionHandler({
clickType: SINGLE_CLICK,
objectType: "port",
id: drawingNewLinkData.srcPort.id,
nodeId: drawingNewLinkData.srcObj.id,
selectedObjectIds: this.ren.activePipeline.getSelectedObjectIds(),
pipelineId: this.ren.activePipeline.id
});
return;
}

if (this.ren.config.enableHighlightUnavailableNodes) {
this.ren.unsetUnavailableNodesHighlighting();
}
Expand All @@ -367,6 +386,12 @@ export default class SVGCanvasUtilsDragNewLink {
}
}

// Returns true if the mouse position is inside a circle with a radius of
// 3px centred at the d3Event x and y.
isClicked(mousePos, d3Event) {
return CanvasUtils.isInside(mousePos, { x: d3Event.x, y: d3Event.y }, 3);
}

// Handles the creation of a link when the end of a new link
// being drawn from a source node is dropped on a target node.
createNewLinkFromDragData(d3Event, trgNode, drawingNewLinkData) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ export default class PromptCanvas extends React.Component {
}

clickActionHandler(source) {
// this.addPromptNode();
if (source.objectType === "port" &&
source.clickType === "SINGLE_CLICK") {
this.addPromptNode(source.nodeId, source.id);
}
}

layoutHandler(node) {
Expand All @@ -115,7 +118,7 @@ export default class PromptCanvas extends React.Component {

editActionHandler(data) {
if (data.editType === "app_addPropmpt") {
this.addPromptNode(data.targetObject);
this.addPromptNode(data.targetObject.id);
}
}

Expand All @@ -135,10 +138,10 @@ export default class PromptCanvas extends React.Component {
return defaultMenu;
}

addNodeHandler(nodeTemplate) {
const promptNode = this.canvasController.getNode(this.promptNodeId);
this.canvasController.deleteNode(this.promptNodeId);
this.canvasController.deleteLink("link_to_prompt");
addNodeHandler(srcNodeId, srcPortId, nodeTemplate, promptNodeId) {
const promptNode = this.canvasController.getNode(promptNodeId);
this.canvasController.deleteNode(promptNodeId);
this.canvasController.deleteLink(this.genPromptLinkId(srcNodeId, srcPortId));

const newNode = this.canvasController.createNode({
nodeTemplate: nodeTemplate,
Expand All @@ -149,51 +152,56 @@ export default class PromptCanvas extends React.Component {

const linksToAdd = this.canvasController.createNodeLinks({
type: "nodeLink",
nodes: [{ id: this.sourceNodeId }],
nodes: [{ id: srcNodeId, portId: srcPortId }],
targetNodes: [{ id: newNode.id }]
});

this.canvasController.addLinks(linksToAdd);

}

addPromptNode(sourceNode) {
this.sourceNodeId = sourceNode.id;
addPromptNode(srcNodeId, srcPortId) {
const srcNode = this.canvasController.getNode(srcNodeId);

const template = Template;
template.app_data.prompt_data = {
addNodeCallback: this.addNodeHandler.bind(this)
addNodeCallback: this.addNodeHandler.bind(this, srcNodeId, srcPortId)
};
const newNode = this.canvasController.createNode({
const promptNode = this.canvasController.createNode({
nodeTemplate: template,
offsetX: sourceNode.x_pos + 200, // Position prompt 200px to right of source node
offsetY: sourceNode.y_pos
offsetX: srcNode.x_pos + 200, // Position prompt 200px to right of source node
offsetY: srcNode.y_pos
});

// Make sure prompt doesn't overlap other nodes.
this.adjustNodePosition(newNode, 100);

// Save the ID of the prompt node for removal, later
this.promptNodeId = newNode.id;
this.adjustNodePosition(promptNode);

// Add the prompt node to the canvas with a link
this.canvasController.addNode(newNode);
this.canvasController.addNode(promptNode);
const linksToAdd = this.canvasController.createNodeLinks({
id: "link_to_prompt",
id: this.genPromptLinkId(srcNodeId, srcPortId),
type: "nodeLink",
nodes: [{ id: sourceNode.id }],
targetNodes: [{ id: this.promptNodeId }]
nodes: [{ id: srcNodeId, portId: srcPortId }],
targetNodes: [{ id: promptNode.id }]
});

this.canvasController.addLinks(linksToAdd);
}

adjustNodePosition(node, yInc) {
genPromptLinkId(srcNodeId, srcPortId) {
return "link_to_prompt_" + srcNodeId + "_" + srcPortId;
}

adjustNodePosition(node) {
let overlapNode = true;
while (overlapNode) {
overlapNode = this.canvasController.getNodes().find((n) => n.x_pos === node.x_pos && n.y_pos === node.y_pos);
overlapNode = this.canvasController.getNodes().find((n) =>
node.x_pos >= n.x_pos &&
node.x_pos <= n.x_pos + n.height &&
node.y_pos >= n.y_pos &&
node.y_pos <= n.y_pos + n.width
);
if (overlapNode) {
node.y_pos += yInc;
node.y_pos += overlapNode.height + 20;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"label": "Type",
"image": "images/custom-canvases/flows/palette/icons/type.svg",
"x_pos": 54,
"y_pos": 250,
"y_pos": 331.2,
"description": "Type node."
}
},
Expand Down Expand Up @@ -80,12 +80,12 @@
"comments": [
{
"id": "0b123469-7d21-43a5-ae84-cbc999990033",
"x_pos": 54,
"y_pos": 43.2,
"width": 288,
"height": 158.4,
"x_pos": 36,
"y_pos": 28.8,
"width": 342,
"height": 231,
"class_name": "d3-comment-rect bkg-col-green-20",
"content": "### Prompt Canvas\n\nThis canvas provides a method to add new nodes to the flow with a prompt. To do this:\n1. Hover over the Type node\n2. In the context toolbar, click the \"Add node with prompt\" button\n3. Select a node type from the prompt. ",
"content": "### Prompt Canvas\n\nThis canvas provides a method to add new nodes to the flow with a prompt. To do this either:\n1. Click one of the ports of the Type node\n2. Select a node type from the prompt. \n\nor:\n1. Hover over the Type node \n2. Click the \"Add node with prompt\" button in the context toolbar",
"associated_id_refs": []
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ export default class PromptReactNode extends React.Component {
}

onClick(nodeTemplate, evt) {
this.props.nodeData.app_data.prompt_data.addNodeCallback(nodeTemplate);
this.props.nodeData.app_data.prompt_data
.addNodeCallback(nodeTemplate, this.props.nodeData.id);
}

onScroll(evt) {
Expand All @@ -46,7 +47,7 @@ export default class PromptReactNode extends React.Component {
}

return (
<div style={{ height: "100%", width: "100%", overflowY: "scroll", backgroundColor: "white" }}
<div style={{ height: "100%", width: "100%", overflowY: "scroll", padding: "5px", backgroundColor: "white" }}
onScroll={this.onScroll} onWheel={this.onScroll}
>
{ nodeDivs }
Expand Down

0 comments on commit 1014e44

Please sign in to comment.