/*! * Copyright (c) 2023, 2024, Oracle and/or its affiliates. */ /** * @file * * Contains the tool to display on elements - to be able to connect them to other elements. * * Clicking the tool dispatches an event upon which an external scripts should perform some * action, e.g. opening a menu or creating and connecting a new element using the Diagram * Builder's public API. * * Dragging outside the tool with the mouse pointer draws a link to the target. */ import mixin from "../mixin.mjs"; const { elementTools, util } = joint; export default class Connect extends elementTools.Connect { preinitialize() { super.preinitialize( ...arguments ); this.name = "connect-button"; this.events = { mousedown: "mousedown", mouseup: "mouseup", mouseleave: "mouseleave", }; this.documentEvents = { mousemove: "drag", touchmove: "drag", mouseup: "dragend", touchend: "dragend", touchcancel: "dragend" }; this.children = [{ tagName: "circle", selector: "button", attributes: { r: 10, fill: "var(--a-diagram-button-background-color, #eee)", stroke: "var(--a-diagram-button-border-color, #666)", cursor: "pointer" } }, { tagName: "text", selector: "label", textContent: "\ue069", attributes: { "font-family": "apex-core-font", "dominant-baseline": "central", "text-anchor": "middle", "pointer-events": "none", fill: "#666", stroke: "none", "style": "user-select: none" } }]; } constructor() { super( ...arguments ); Object.assign( this, mixin ); } onRender() { this.mPosition(); super.onRender(); } mousedown( e ) { this.isMouseDown = true; e.stopPropagation(); } mouseup( e ) { const { position, x, y } = this.options; this.isMouseDown = false; this.relatedView.notify( "element:connectbutton:pointerup", this, position, { x, y }, e ); } mouseleave( e ) { if ( this.isMouseDown && !this.isDragging ) { this.dragLinkStart( e ); } } dragLinkStart( e ) { const { paper, relatedView } = this; const normalizedEvent = util.normalizeEvent( e ); const { x, y } = paper.clientToLocalPoint( normalizedEvent.clientX, normalizedEvent.clientY ); this.isDragging = true; const linkView = relatedView.dragLinkStart( normalizedEvent, this.getMagnetNode(), x, y, this.options.position ); // add the origin side so we can determine which side to loop to (if there is a loop) on pointer events linkView.eventData( e, { originSide: this.options.position } ); this.relatedView.notify( "element:connectbutton:linkingstart", this, this.relatedView.eventData( e ).linkView, e ); paper.undelegateEvents(); this.delegateDocumentEvents( null, normalizedEvent.data ); // Instead of focusing this tool, hide all tools - that will prevent linking to the tool el (which // is part of the element) and anchoring the link "outside" the parent element. this.parentView.hide(); } dragend( e ) { this.isMouseDown = false; this.isDragging = false; super.dragend( e ); } }