/*! * Copyright (c) 2023, 2026, Oracle and/or its affiliates. */ /** * @file * * Contains a tool to display on links at a given length or ratio. */ const { V, linkTools, util } = joint; const COLOR_STROKE = "var(--a-diagram-link-placeholder-border-color, none)"; const COLOR_FILL = "var(--a-diagram-link-placeholder-background-color, #666)"; const COLOR_GLYPH = "var(--a-diagram-link-placeholder-text-color, #fff)"; const COLOR_GUIDE_LINE = "var(--a-diagram-link-border-color, #666)"; export default class AddElementButton extends linkTools.Button { guideLineHidden = true; preinitialize() { super.preinitialize( ...arguments ); this.name = "add-element-button"; this.events = { "mousedown": "onPointerDown", "touchstart": "onPointerDown", "mouseup": "onPointerUp", "touchend": "onPointerUp", "touchcancel": "onPointerUp" }; this.children = [{ tagName: "path", selector: "guideLine", attributes: { fill: "none", "pointer-events": "none", stroke: COLOR_GUIDE_LINE, "stroke-dasharray": "4 4", "stroke-width": 2, d: "M 0 0 0 0" } }, { tagName: "circle", selector: "button", attributes: { r: 15, fill: COLOR_FILL, stroke: COLOR_STROKE, cursor: "pointer" } }, { tagName: "text", selector: "label", textContent: "\ue069", attributes: { "font-family": "apex-core-font", "font-size": 20, "dominant-baseline": "central", "text-anchor": "middle", "pointer-events": "none", fill: COLOR_GLYPH, stroke: "none", x: 0, style: "user-select: none" } }]; } onRender() { super.onRender(); this.updateGuideLine(); } show() { super.show(); this.updateGuideLine(); } hide() { super.hide(); this.clearGuideLine(); } onPointerDown( e ) { super.onPointerDown( e ); this.relatedView.notify( "link:addelement:pointerdown", this, this.getLinkPoint(), e ); } onPointerUp( e ) { this.relatedView.notify( "link:addelement:pointerup", this, this.getLinkPoint(), e ); } getLinkPoint() { const view = this.relatedView; const { distance = 0 } = this.options; if ( util.isPercentage( distance ) ) { return view.getPointAtRatio( parseFloat( distance ) / 100 ); } return view.getPointAtLength( distance ); } update() { super.update( ...arguments ); this.updateGuideLine(); return this; } clearGuideLine() { if ( !this.guideLineHidden ) { this.childNodes.guideLine.setAttribute( "d", "M 0 0 0 0" ); this.guideLineHidden = true; } } updateGuideLine() { const { guideLine = false } = this.options; if ( !guideLine || !this.isVisible() ) { this.clearGuideLine(); return; } const guideLineEl = this.childNodes.guideLine; const linkPoint = this.getLinkPoint(); const buttonMatrix = this.getCellMatrix(); if ( !linkPoint || !Number.isFinite( linkPoint.x ) || !Number.isFinite( linkPoint.y ) || !Number.isFinite( buttonMatrix.e ) || !Number.isFinite( buttonMatrix.f ) ) { this.clearGuideLine(); return; } const localLinkPoint = V.transformPoint( linkPoint, buttonMatrix.inverse() ); guideLineEl.setAttribute( "d", `M 0 0 ${localLinkPoint.x} ${localLinkPoint.y}` ); this.guideLineHidden = false; } }