UNPKG

@eclipse-glsp/client

Version:

A sprotty-based client for GLSP

235 lines 11.1 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var EdgeCreationTool_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.EdgeCreationToolMouseListener = exports.EdgeCreationTool = void 0; /******************************************************************************** * Copyright (c) 2019-2024 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. * * This Source Code may also be made available under the following Secondary * Licenses when the conditions for such availability set forth in the Eclipse * Public License v. 2.0 are satisfied: GNU General Public License, version 2 * with the GNU Classpath Exception which is available at * https://www.gnu.org/software/classpath/license.html. * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ const sprotty_1 = require("@eclipse-glsp/sprotty"); const inversify_1 = require("inversify"); const drag_aware_mouse_listener_1 = require("../../../base/drag-aware-mouse-listener"); const css_feedback_1 = require("../../../base/feedback/css-feedback"); const tool_1 = require("../../../base/tool-manager/tool"); const model_1 = require("../../../model"); const grid_1 = require("../../grid/grid"); const base_tools_1 = require("../base-tools"); const dangling_edge_feedback_1 = require("./dangling-edge-feedback"); const edge_creation_tool_feedback_1 = require("./edge-creation-tool-feedback"); /** * Tool to create connections in a Diagram, by selecting a source and target node. */ let EdgeCreationTool = EdgeCreationTool_1 = class EdgeCreationTool extends base_tools_1.BaseCreationTool { constructor() { super(...arguments); this.isTriggerAction = sprotty_1.TriggerEdgeCreationAction.is; } get id() { return EdgeCreationTool_1.ID; } doEnable() { this.toolFeedback(); this.creationListener(); this.trackFeedbackEdge(); } toolFeedback() { const toolFeedback = this.createFeedbackEmitter() .add((0, css_feedback_1.cursorFeedbackAction)(css_feedback_1.CursorCSS.OPERATION_NOT_ALLOWED), (0, css_feedback_1.cursorFeedbackAction)()) .submit(); this.toDisposeOnDisable.push(toolFeedback); } creationListener() { const creationListener = new EdgeCreationToolMouseListener(this.triggerAction, this.actionDispatcher, this.typeHintProvider, this, this.grid ? this.grid.x / 2 : undefined); this.toDisposeOnDisable.push(creationListener, this.mouseTool.registerListener(creationListener)); } trackFeedbackEdge() { const mouseMovingFeedback = new edge_creation_tool_feedback_1.FeedbackEdgeEndMovingMouseListener(this.anchorRegistry, this.feedbackDispatcher); this.toDisposeOnDisable.push(mouseMovingFeedback, this.mouseTool.registerListener(mouseMovingFeedback)); } }; exports.EdgeCreationTool = EdgeCreationTool; EdgeCreationTool.ID = 'tool_create_edge'; __decorate([ (0, inversify_1.inject)(sprotty_1.AnchorComputerRegistry), __metadata("design:type", sprotty_1.AnchorComputerRegistry) ], EdgeCreationTool.prototype, "anchorRegistry", void 0); __decorate([ (0, inversify_1.inject)(sprotty_1.TYPES.ITypeHintProvider), __metadata("design:type", Object) ], EdgeCreationTool.prototype, "typeHintProvider", void 0); __decorate([ (0, inversify_1.optional)(), (0, inversify_1.inject)(sprotty_1.TYPES.Grid), __metadata("design:type", Object) ], EdgeCreationTool.prototype, "grid", void 0); exports.EdgeCreationTool = EdgeCreationTool = EdgeCreationTool_1 = __decorate([ (0, inversify_1.injectable)() ], EdgeCreationTool); class EdgeCreationToolMouseListener extends drag_aware_mouse_listener_1.DragAwareMouseListener { constructor(triggerAction, actionDispatcher, typeHintProvider, tool, dragSensitivity) { super(dragSensitivity); this.triggerAction = triggerAction; this.actionDispatcher = actionDispatcher; this.typeHintProvider = typeHintProvider; this.tool = tool; this.dragSensitivity = dragSensitivity; this.allowedTarget = false; this.pendingDynamicCheck = false; this.proxyEdge = new model_1.GEdge(); this.proxyEdge.type = triggerAction.elementTypeId; this.cursorFeedback = tool.createFeedbackEmitter(); this.feedbackEdgeFeedback = tool.createFeedbackEmitter(); } nonDraggingMouseUp(element, event) { const result = []; if (event.button === 0) { if (!this.isSourceSelected()) { if (this.currentTarget && this.allowedTarget) { this.source = this.currentTarget.id; this.feedbackEdgeFeedback .add(dangling_edge_feedback_1.DrawFeedbackEdgeAction.create({ elementTypeId: this.triggerAction.elementTypeId, sourceId: this.source }), dangling_edge_feedback_1.RemoveFeedbackEdgeAction.create()) .submit(); } } else if (this.currentTarget && this.allowedTarget) { this.target = this.currentTarget.id; } if (this.source && this.target) { result.push(this.getCreateOperation(element, event, this.source, this.target)); if (!this.isContinuousMode(element, event)) { result.push(tool_1.EnableDefaultToolsAction.create()); } else { this.dispose(); } } } else if (event.button === 2) { this.dispose(); result.push(tool_1.EnableDefaultToolsAction.create()); } return result; } /** * Determines wether the tool should run in continuous mode (also called stamp mode) or not. * If continuous mode is enabled, the tool will stay after a successful creation. * The user can then create more elements of the same type without having to re-trigger the tool. * By default, continuous mode is enabled if the user holds the CTRL key. * @param element the current model element * @param event */ isContinuousMode(element, event) { return (0, sprotty_1.isCtrlOrCmd)(event); } getCreateOperation(element, event, sourceElementId, targetElementId) { return sprotty_1.CreateEdgeOperation.create({ elementTypeId: this.triggerAction.elementTypeId, sourceElementId, targetElementId, args: this.getCreateEdgeOperationArgs(element, event) }); } getCreateEdgeOperationArgs(ctx, event) { return { ...this.triggerAction.args }; } isSourceSelected() { return this.source !== undefined; } isTargetSelected() { return this.target !== undefined; } mouseOver(target, event) { const newCurrentTarget = (0, sprotty_1.findParentByFeature)(target, sprotty_1.isConnectable); if (newCurrentTarget !== this.currentTarget) { this.pendingDynamicCheck = false; this.currentTarget = newCurrentTarget; if (this.currentTarget) { if (!this.isSourceSelected()) { this.allowedTarget = this.canConnect(newCurrentTarget, 'source'); } else if (!this.isTargetSelected()) { this.allowedTarget = this.canConnect(newCurrentTarget, 'target'); } if (this.pendingDynamicCheck) { return [(0, css_feedback_1.cursorFeedbackAction)(css_feedback_1.CursorCSS.EDGE_CHECK_PENDING)]; } } else { this.allowedTarget = false; } return [this.updateEdgeFeedback()]; } return []; } updateEdgeFeedback() { if (this.allowedTarget) { const action = !this.isSourceSelected() ? (0, css_feedback_1.cursorFeedbackAction)(css_feedback_1.CursorCSS.EDGE_CREATION_SOURCE) : (0, css_feedback_1.cursorFeedbackAction)(css_feedback_1.CursorCSS.EDGE_CREATION_TARGET); return action; } return (0, css_feedback_1.cursorFeedbackAction)(css_feedback_1.CursorCSS.OPERATION_NOT_ALLOWED); } canConnect(element, role) { var _a; if (!element || !(0, sprotty_1.isConnectable)(element) || !element.canConnect(this.proxyEdge, role)) { return false; } if (!this.isDynamic(this.proxyEdge.type)) { return true; } const sourceElement = (_a = this.source) !== null && _a !== void 0 ? _a : element; const targetElement = this.source ? element : undefined; this.pendingDynamicCheck = true; // Request server edge check this.actionDispatcher .request(sprotty_1.RequestCheckEdgeAction.create({ sourceElement, targetElement, edgeType: this.proxyEdge.type })) .then(result => { if (this.pendingDynamicCheck) { this.allowedTarget = result.isValid; this.actionDispatcher.dispatch(this.updateEdgeFeedback()); this.pendingDynamicCheck = false; } }) .catch(err => console.error('Dynamic edge check failed with: ', err)); // Temporarily mark the target as invalid while we wait for the server response, // so a fast-clicking user doesn't get a chance to create the edge in the meantime. return false; } isDynamic(edgeTypeId) { var _a; const typeHint = this.typeHintProvider.getEdgeTypeHint(edgeTypeId); return (_a = typeHint === null || typeHint === void 0 ? void 0 : typeHint.dynamic) !== null && _a !== void 0 ? _a : false; } dispose() { this.source = undefined; this.target = undefined; this.currentTarget = undefined; this.allowedTarget = false; this.feedbackEdgeFeedback.dispose(); this.cursorFeedback.dispose(); super.dispose(); } } exports.EdgeCreationToolMouseListener = EdgeCreationToolMouseListener; //# sourceMappingURL=edge-creation-tool.js.map