diff --git a/src/component/mxgraph/StyleUtils.ts b/src/component/mxgraph/StyleUtils.ts index d807dcab03..3f2e27ec4b 100644 --- a/src/component/mxgraph/StyleUtils.ts +++ b/src/component/mxgraph/StyleUtils.ts @@ -53,6 +53,10 @@ export enum StyleDefault { DEFAULT_OVERLAY_STROKE_WIDTH = 1, DEFAULT_OVERLAY_FONT_SIZE = DEFAULT_FONT_SIZE, DEFAULT_OVERLAY_FONT_COLOR = DEFAULT_FONT_COLOR, + // Edge + SEQUENCE_FLOW_CONDITIONAL_FROM_ACTIVITY_MARKER_FILL_COLOR = 'White', + MESSAGE_FLOW_MARKER_START_FILL_COLOR = 'White', + MESSAGE_FLOW_MARKER_END_FILL_COLOR = 'White', } export enum StyleIdentifier { @@ -65,6 +69,10 @@ export enum StyleIdentifier { BPMN_STYLE_MESSAGE_FLOW_ICON = 'bpmn.messageFlowIcon', BPMN_STYLE_EVENT_BASED_GATEWAY_KIND = 'bpmn.gatewayKind', BPMN_STYLE_EXTRA_CSS_CLASSES = 'bpmn.extra.css.classes', + // for edge + EDGE = 'bpmn.edge', + EDGE_START_FILL_COLOR = 'bpmn.edge.startFillColor', + EDGE_END_FILL_COLOR = 'bpmn.edge.endFillColor', } /* eslint-disable @typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types */ diff --git a/src/component/mxgraph/config/ShapeConfigurator.ts b/src/component/mxgraph/config/ShapeConfigurator.ts index 5b2276672b..41c1a15ae3 100644 --- a/src/component/mxgraph/config/ShapeConfigurator.ts +++ b/src/component/mxgraph/config/ShapeConfigurator.ts @@ -37,6 +37,7 @@ import { StyleIdentifier } from '../StyleUtils'; import { computeAllBpmnClassNames, extractBpmnKindFromStyle } from '../style-helper'; import { MxGraphCustomOverlay } from '../overlay/custom-overlay'; import { OverlayBadgeShape } from '../overlay/shapes'; +import { BpmnConnector } from '../shape/edges'; /** * @internal @@ -76,6 +77,7 @@ export default class ShapeConfigurator { mxgraph.mxCellRenderer.registerShape(ShapeBpmnElementKind.TEXT_ANNOTATION, TextAnnotationShape); // shapes for flows + mxgraph.mxCellRenderer.registerShape(StyleIdentifier.EDGE, BpmnConnector); mxgraph.mxCellRenderer.registerShape(StyleIdentifier.BPMN_STYLE_MESSAGE_FLOW_ICON, MessageFlowIconShape); } diff --git a/src/component/mxgraph/config/StyleConfigurator.ts b/src/component/mxgraph/config/StyleConfigurator.ts index 22a8243490..d7bf7a4aac 100644 --- a/src/component/mxgraph/config/StyleConfigurator.ts +++ b/src/component/mxgraph/config/StyleConfigurator.ts @@ -56,9 +56,11 @@ export default class StyleConfigurator { style[mxgraph.mxConstants.STYLE_DASH_PATTERN] = '8 5'; style[mxgraph.mxConstants.STYLE_STARTARROW] = mxgraph.mxConstants.ARROW_OVAL; style[mxgraph.mxConstants.STYLE_STARTSIZE] = 8; - style[mxgraph.mxConstants.STYLE_STARTFILL] = false; + style[mxgraph.mxConstants.STYLE_STARTFILL] = true; + style[StyleIdentifier.EDGE_START_FILL_COLOR] = StyleDefault.MESSAGE_FLOW_MARKER_START_FILL_COLOR; style[mxgraph.mxConstants.STYLE_ENDARROW] = mxgraph.mxConstants.ARROW_BLOCK_THIN; - style[mxgraph.mxConstants.STYLE_ENDFILL] = false; + style[mxgraph.mxConstants.STYLE_ENDFILL] = true; + style[StyleIdentifier.EDGE_END_FILL_COLOR] = StyleDefault.MESSAGE_FLOW_MARKER_END_FILL_COLOR; }, ], [ @@ -84,7 +86,8 @@ export default class StyleConfigurator { (style: StyleMap) => { style[mxgraph.mxConstants.STYLE_STARTARROW] = mxgraph.mxConstants.ARROW_DIAMOND_THIN; style[mxgraph.mxConstants.STYLE_STARTSIZE] = 18; - style[mxgraph.mxConstants.STYLE_STARTFILL] = false; + style[mxgraph.mxConstants.STYLE_STARTFILL] = true; + style[StyleIdentifier.EDGE_START_FILL_COLOR] = StyleDefault.SEQUENCE_FLOW_CONDITIONAL_FROM_ACTIVITY_MARKER_FILL_COLOR; }, ], ]); @@ -238,6 +241,7 @@ export default class StyleConfigurator { private configureDefaultEdgeStyle(): void { const style = this.getDefaultEdgeStyle(); + style[mxgraph.mxConstants.STYLE_SHAPE] = StyleIdentifier.EDGE; style[mxgraph.mxConstants.STYLE_EDGE] = mxgraph.mxConstants.EDGESTYLE_SEGMENT; style[mxgraph.mxConstants.STYLE_ENDSIZE] = 12; style[mxgraph.mxConstants.STYLE_STROKEWIDTH] = 1.5; diff --git a/src/component/mxgraph/shape/edges.ts b/src/component/mxgraph/shape/edges.ts new file mode 100644 index 0000000000..d7801ca270 --- /dev/null +++ b/src/component/mxgraph/shape/edges.ts @@ -0,0 +1,71 @@ +/** + * Copyright 2021 Bonitasoft S.A. + * + * Licensed 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 { mxgraph } from '../initializer'; +import { mxAbstractCanvas2D, mxPoint } from 'mxgraph'; +import { StyleIdentifier } from '../StyleUtils'; // for types + +/* eslint-disable @typescript-eslint/ban-ts-comment */ +export class BpmnConnector extends mxgraph.mxConnector { + constructor(points: mxPoint[], stroke: string, strokewidth?: number) { + super(points, stroke, strokewidth); + } + + paintEdgeShape(c: mxAbstractCanvas2D, pts: mxPoint[]): void { + // The indirection via functions for markers is needed in + // order to apply the offsets before painting the line and + // paint the markers after painting the line. + // @ts-ignore wrong type returned by typed-mxgraph@1.0.2 + const sourceMarker: () => void = this.createMarker(c, pts, true); + // @ts-ignore wrong type returned by typed-mxgraph@1.0.2 + const targetMarker: () => void = this.createMarker(c, pts, false); + + this.paintEdgeLine(c, pts); + + // Disables shadows, dashed styles + c.setShadow(false); + c.setDashed(false, false); + + if (sourceMarker != null) { + c.setFillColor(mxgraph.mxUtils.getValue(this.style, StyleIdentifier.EDGE_START_FILL_COLOR, this.stroke)); + sourceMarker(); + } + + if (targetMarker != null) { + c.setFillColor(mxgraph.mxUtils.getValue(this.style, StyleIdentifier.EDGE_END_FILL_COLOR, this.stroke)); + targetMarker(); + } + } + + // taken from mxPolyline, required as we cannot call mxPolyline method here (parent of the parent) + // we only support non STYLE_CURVED here (is possible with parent class) + private paintEdgeLine(c: mxAbstractCanvas2D, pts: mxPoint[]): void { + const prev = getPointerEventsValue(c); + setPointerEventsValue(c, 'stroke'); + this.paintLine(c, pts, this.isRounded); + setPointerEventsValue(c, prev); + } +} + +function getPointerEventsValue(c: mxAbstractCanvas2D): string { + return c instanceof mxgraph.mxSvgCanvas2D ? c.pointerEventsValue : null; +} + +function setPointerEventsValue(c: mxAbstractCanvas2D, value: string): void { + if (c instanceof mxgraph.mxSvgCanvas2D) { + c.pointerEventsValue = value; + } +}