@eclipse-glsp/client
Version:
A sprotty-based client for GLSP
197 lines • 10.3 kB
JavaScript
"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 NodeCreationTool_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.NodeCreationToolMouseListener = exports.NodeInsertTrackingListener = exports.NodeCreationTool = void 0;
/********************************************************************************
* Copyright (c) 2020-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");
require("../../../../css/ghost-element.css");
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 add_template_element_1 = require("../../element-template/add-template-element");
const mouse_tracking_element_position_listener_1 = require("../../element-template/mouse-tracking-element-position-listener");
const remove_template_element_1 = require("../../element-template/remove-template-element");
const base_tools_1 = require("../base-tools");
const insert_indicator_1 = require("./insert-indicator");
let NodeCreationTool = NodeCreationTool_1 = class NodeCreationTool extends base_tools_1.BaseCreationTool {
constructor() {
super(...arguments);
this.isTriggerAction = sprotty_1.TriggerNodeCreationAction.is;
}
get id() {
return NodeCreationTool_1.ID;
}
doEnable() {
var _a;
const ghostElement = (_a = this.triggerAction.ghostElement) !== null && _a !== void 0 ? _a : { template: this.modelFactory.createSchema(this.createInsertIndicator()) };
this.toDisposeOnDisable.push(this.createGhostElementTracker(ghostElement, 'middle'));
this.toDisposeOnDisable.push(this.createNodeCreationListener(ghostElement));
this.toDisposeOnDisable.push(this.createNodeCreationCursorFeedback().submit());
}
createInsertIndicator() {
return new insert_indicator_1.InsertIndicator();
}
createGhostElementTracker(ghostElement, position) {
const trackingListener = new NodeInsertTrackingListener((0, add_template_element_1.getTemplateElementId)(ghostElement.template), this.triggerAction.elementTypeId, this, position, this.editorContext);
return new sprotty_1.DisposableCollection(trackingListener, this.mouseTool.registerListener(trackingListener));
}
createNodeCreationListener(ghostElement) {
const toolListener = new NodeCreationToolMouseListener(this.triggerAction, this, ghostElement);
return new sprotty_1.DisposableCollection(toolListener, this.mouseTool.registerListener(toolListener));
}
createNodeCreationCursorFeedback() {
return this.createFeedbackEmitter().add((0, css_feedback_1.cursorFeedbackAction)(css_feedback_1.CursorCSS.NODE_CREATION), (0, css_feedback_1.cursorFeedbackAction)());
}
};
exports.NodeCreationTool = NodeCreationTool;
NodeCreationTool.ID = 'tool_create_node';
__decorate([
(0, inversify_1.inject)(sprotty_1.TYPES.IChangeBoundsManager),
__metadata("design:type", Object)
], NodeCreationTool.prototype, "changeBoundsManager", void 0);
__decorate([
(0, inversify_1.inject)(sprotty_1.TYPES.IContainerManager),
__metadata("design:type", Object)
], NodeCreationTool.prototype, "containerManager", void 0);
__decorate([
(0, inversify_1.inject)(sprotty_1.TYPES.IModelFactory),
__metadata("design:type", Object)
], NodeCreationTool.prototype, "modelFactory", void 0);
exports.NodeCreationTool = NodeCreationTool = NodeCreationTool_1 = __decorate([
(0, inversify_1.injectable)()
], NodeCreationTool);
class NodeInsertTrackingListener extends mouse_tracking_element_position_listener_1.MouseTrackingElementPositionListener {
constructor(elementId, elementTypeId, tool, cursorPosition = 'top-left', editorContext) {
super(elementId, tool, cursorPosition, editorContext);
this.elementTypeId = elementTypeId;
this.tool = tool;
}
addMoveFeedback(move, ctx, event) {
super.addMoveFeedback(move, ctx, event);
const element = move.elementMoves[0].element;
const location = move.elementMoves[0].toPosition;
const insert = this.tool.containerManager.insert(element, location, this.elementTypeId, { evt: event });
this.tool.containerManager.addInsertFeedback(this.moveGhostFeedback, insert, ctx, event);
}
}
exports.NodeInsertTrackingListener = NodeInsertTrackingListener;
class NodeCreationToolMouseListener extends drag_aware_mouse_listener_1.DragAwareMouseListener {
constructor(triggerAction, tool, ghostElement) {
super();
this.triggerAction = triggerAction;
this.tool = tool;
this.ghostElement = ghostElement;
this.cursorFeedback = tool.createFeedbackEmitter();
this.ghostElementFeedback = tool.createFeedbackEmitter();
this.ghostElementId = (0, add_template_element_1.getTemplateElementId)(ghostElement.template);
this.createGhostElement(ghostElement);
}
get elementTypeId() {
return this.triggerAction.elementTypeId;
}
nonDraggingMouseUp(ctx, event) {
const result = [];
const insert = this.getTrackedInsert(ctx, event);
if (insert.valid) {
result.push(this.getCreateOperation(ctx, event, insert));
}
if (this.isContinuousMode(ctx, event)) {
// we continue in stamp mode so we keep the ghost but dispose everything else
this.disposeAllButGhostElement();
return result;
}
if (insert.valid) {
// we keep the ghost element until the next update to avoid flickering during insert
this.ghostElementFeedback.discard();
}
else {
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 ctx the current model context
* @param event
*/
isContinuousMode(ctx, event) {
return (0, sprotty_1.isCtrlOrCmd)(event);
}
getCreateOperation(ctx, event, insert) {
var _a;
return sprotty_1.CreateNodeOperation.create(this.elementTypeId, {
location: insert.location,
containerId: (_a = insert.container) === null || _a === void 0 ? void 0 : _a.id,
args: this.getCreateNodeOperationArgs(insert, ctx, event)
});
}
getCreateNodeOperationArgs(insert, ctx, event) {
let args = { ...this.triggerAction.args };
const ghostElement = this.getGhostElement(ctx, event);
if (ghostElement) {
const ghostDimensions = (0, sprotty_1.isBoundsAware)(ghostElement) ? sprotty_1.Bounds.dimension(ghostElement.bounds) : sprotty_1.Dimension.ZERO;
args = {
...args,
'ghost-x': ghostElement.position.x,
'ghost-y': ghostElement.position.y,
'ghost-width': ghostDimensions.width,
'ghost-height': ghostDimensions.height
};
}
return args;
}
createGhostElement(ghostElement) {
const templates = [ghostElement.template];
this.ghostElementFeedback.add(add_template_element_1.AddTemplateElementsAction.create({ templates, addClasses: [css_feedback_1.CSS_HIDDEN, css_feedback_1.CSS_GHOST_ELEMENT] }), remove_template_element_1.RemoveTemplateElementsAction.create({ templates }));
this.ghostElementFeedback.submit();
return (0, add_template_element_1.getTemplateElementId)(ghostElement.template);
}
getGhostElement(ctx, event) {
const ghostElement = ctx.index.getById(this.ghostElementId);
return ghostElement && (0, sprotty_1.isMoveable)(ghostElement) ? ghostElement : undefined;
}
getTrackedInsert(ctx, event) {
const ghostElement = this.getGhostElement(ctx, event);
if (!ghostElement) {
return { elementTypeId: this.elementTypeId, location: sprotty_1.Point.ORIGIN, valid: false, options: { evt: event } };
}
return this.tool.containerManager.insert(ghostElement, ghostElement.position, this.elementTypeId, { evt: event });
}
disposeAllButGhostElement() {
super.dispose();
}
dispose() {
this.ghostElementFeedback.dispose();
this.disposeAllButGhostElement();
}
}
exports.NodeCreationToolMouseListener = NodeCreationToolMouseListener;
//# sourceMappingURL=node-creation-tool.js.map