MohammadMu99 commented on code in PR #4015: URL: https://github.com/apache/incubator-kie-tools/pull/4015#discussion_r4411484792
########## packages/bpmn-editor/src/mutations/repositionEdgeLabel.ts: ########## @@ -0,0 +1,296 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { BPMN20__tDefinitions } from "@kie-tools/bpmn-marshaller/dist/schemas/bpmn-2_0/ts-gen/types"; +import { DC__Bounds, DC__Point } from "@kie-tools/xyflow-react-kie-diagram/dist/maths/model"; +import { generateUuid } from "@kie-tools/xyflow-react-kie-diagram/dist/uuid/uuid"; +import { Normalized } from "../normalization/normalize"; +import { addOrGetProcessAndDiagramElements } from "./addOrGetProcessAndDiagramElements"; + +/** + * Pins the label of a BPMNEdge to the given bounds. Labels without bounds are positioned automatically. + */ +export function repositionEdgeLabel({ + definitions, + __readonly_edgeIndex, + __readonly_bounds, +}: { + definitions: Normalized<BPMN20__tDefinitions>; + __readonly_edgeIndex: number; + __readonly_bounds: DC__Bounds; +}) { + const { diagramElements } = addOrGetProcessAndDiagramElements({ definitions }); + + const diagramElement = diagramElements[__readonly_edgeIndex]; + if (diagramElement?.__$$element !== "bpmndi:BPMNEdge") { + throw new Error("BPMN MUTATION: Can't reposition the label of an element that is not a BPMNEdge."); + } + + if (!isFiniteBounds(__readonly_bounds)) { + throw new Error("BPMN MUTATION: Can't reposition the label of a BPMNEdge to invalid bounds."); + } + + diagramElement["bpmndi:BPMNLabel"] ??= { "@_id": generateUuid() }; + diagramElement["bpmndi:BPMNLabel"]["dc:Bounds"] = { + "@_x": __readonly_bounds["@_x"], + "@_y": __readonly_bounds["@_y"], + "@_width": __readonly_bounds["@_width"], + "@_height": __readonly_bounds["@_height"], + }; +} + +/** + * Runs `updateWaypoints` and then moves the edge's label (if it has explicit bounds) so that it stays at the same + * place relative to the edge path, like the label was attached to it. + * + * `referenceEdge` is the edge as it was before the ongoing gesture. Calculating from it doesn't accumulate errors during + * a drag. It's ignored when it doesn't match the current label anymore, as the label or the edge changed since then. + */ +export function updateEdgeWaypointsKeepingLabelAttached( + edge: EdgeWithLabel, + updateWaypoints: () => void, + referenceEdge?: EdgeWithLabel +) { + const labelBounds = edge["bpmndi:BPMNLabel"]?.["dc:Bounds"]; + if (!labelBounds) { + updateWaypoints(); + return; + } + + const source = referenceEdge && isReferenceOf(referenceEdge, edge) ? referenceEdge : edge; + const previousBounds = { ...source["bpmndi:BPMNLabel"]!["dc:Bounds"]! }; + const previousWaypoints = copyWaypoints(source["di:waypoint"]); + + updateWaypoints(); + + const newBounds = getEdgeLabelBoundsAfterWaypointsChange({ + __readonly_labelBounds: previousBounds, + __readonly_previousWaypoints: previousWaypoints, + __readonly_newWaypoints: edge["di:waypoint"], + }); + + if (newBounds["@_x"] !== labelBounds["@_x"] || newBounds["@_y"] !== labelBounds["@_y"]) { + labelBounds["@_x"] = newBounds["@_x"]; + labelBounds["@_y"] = newBounds["@_y"]; + } +} + +function isReferenceOf(referenceEdge: EdgeWithLabel, edge: EdgeWithLabel) { + const referenceBounds = referenceEdge["bpmndi:BPMNLabel"]?.["dc:Bounds"]; + const labelBounds = edge["bpmndi:BPMNLabel"]?.["dc:Bounds"]; + if ( Review Comment: Thanks for checking this! The reference edge is found by its BPMNEdge id, so it can't come from another edge, even if two labels have the same size. I didn't add @_x/@_y because the label moves during a drag. After the first step its x/y no longer match, so the reference would be rejected and the label would start to drift. The position is already checked: the reference must rebuild the current label position (within 0.01). In 3782596 I also added a label id check, so only the same label can match. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
