UNPKG

devexpress-diagram

Version:

DevExpress Diagram Control

156 lines (146 loc) 9.01 kB
import { Connector, ConnectorPosition } from "../../Model/Connectors/Connector"; import { DiagramMouseEvent, MouseEventElementType } from "../Event"; import { MouseHandlerDraggingState } from "./MouseHandlerDraggingState"; import { DeleteConnectionHistoryItem } from "../../History/Common/DeleteConnectionHistoryItem"; import { AddConnectionHistoryItem } from "../../History/Common/AddConnectionHistoryItem"; import { MouseHandler } from "../MouseHandler"; import { History } from "../../History/History"; import { DiagramModel } from "../../Model/Model"; import { ItemKey, DiagramItem } from "../../Model/DiagramItem"; import { ModelUtils } from "../../Model/ModelUtils"; import { IVisualizerManager } from "../Visualizers/VisualizersManager"; import { ConnectionPointInfo } from "../Visualizers/ConnectionPointsVisualizer"; import { ConnectionTargetInfo } from "../Visualizers/ConnectionTargetVisualizer"; export abstract class MouseHandlerMoveConnectorPointStateBase extends MouseHandlerDraggingState { connector: Connector; pointIndex: number; pointPosition: ConnectorPosition; oppositePointPosition: ConnectorPosition; oppositeItem: DiagramItem; oppositeConnectionPointIndex: number; targetItem: DiagramItem; constructor(handler: MouseHandler, history: History, protected model: DiagramModel, protected visualizerManager: IVisualizerManager) { super(handler, history); } finish(): void { this.visualizerManager.resetConnectionTarget(); this.visualizerManager.resetConnectionPoints(); super.finish(); } onMouseDown(evt: DiagramMouseEvent): void { super.onMouseDown(evt); if(this.connector) this.handler.addInteractingItem(this.connector); } onMouseMove(evt: DiagramMouseEvent): void { super.onMouseMove(evt); if(!this.allowAttachToObjects(evt, false, false)) { this.visualizerManager.resetConnectionTarget(); this.visualizerManager.resetConnectionPoints(); } else if(this.connector) { let item = this.connector.getExtremeItem(this.pointPosition); this.visualizerManager.setConnectionTarget(item, evt.source.type); const pointIndex = this.connector.getExtremeConnectionPointIndex(this.pointPosition); if(!item && this.oppositeConnectionPointIndex !== -1 || !this.allowAttachToObjects(evt, true, false)) item = this.model.findItem(evt.source.key); this.visualizerManager.setConnectionPoints(item, evt.source.type, pointIndex, true); } } onApplyChanges(evt: DiagramMouseEvent): void { let point = this.getSnappedPoint(evt, evt.modelPoint); if(this.pointPosition !== undefined) { if(this.oppositePointPosition === undefined) { this.oppositePointPosition = this.getOppositePointPosition(); this.oppositeItem = this.connector.getExtremeItem(this.oppositePointPosition); this.oppositeConnectionPointIndex = this.connector.getExtremeConnectionPointIndex(this.oppositePointPosition); } this.targetItem = this.model.findItem(evt.source.key); const item = this.allowAttachToObjects(evt, true, true) ? this.targetItem : undefined; let connectionPointIndex = -1; if(evt.source.type === MouseEventElementType.ShapeConnectionPoint) connectionPointIndex = parseInt(evt.source.value); if(item && (evt.source.type === MouseEventElementType.Shape || evt.source.type === MouseEventElementType.ShapeConnectionPoint) && (this.connector.getExtremeItem(this.oppositePointPosition) !== item || (connectionPointIndex !== -1 && this.oppositeConnectionPointIndex !== -1 && connectionPointIndex !== this.oppositeConnectionPointIndex))) { if(this.connector.getExtremeItem(this.pointPosition) !== item || this.connector.getExtremeConnectionPointIndex(this.pointPosition) !== connectionPointIndex) { if(this.connector.getExtremeItem(this.pointPosition)) this.history.addAndRedo(new DeleteConnectionHistoryItem(this.connector, this.pointPosition)); this.history.addAndRedo(new AddConnectionHistoryItem(this.connector, item, connectionPointIndex, this.pointPosition)); if(this.oppositeItem) this.updateOppositeItemConnectionPointIndex(connectionPointIndex); } point = item.getConnectionPointPosition(connectionPointIndex, this.connector.points[this.pointIndex + (this.pointPosition === ConnectorPosition.End ? -1 : 1)] ); this.visualizerManager.setConnectionPointIndex(connectionPointIndex); } else if(this.connector.getExtremeItem(this.pointPosition)) { this.history.addAndRedo(new DeleteConnectionHistoryItem(this.connector, this.pointPosition)); if(this.oppositeItem) this.updateOppositeItemConnectionPointIndex(this.oppositeConnectionPointIndex); } } ModelUtils.moveConnectorPoint(this.history, this.connector, this.pointIndex, point); ModelUtils.updateConnectorAttachedPoints(this.history, this.model, this.connector); this.handler.tryUpdateModelSize(); } updateOppositeItemConnectionPointIndex(connectionPointIndex: number): void { const pointIndex = connectionPointIndex === -1 ? -1 : this.oppositeConnectionPointIndex; if(pointIndex !== this.connector.getExtremeConnectionPointIndex(this.oppositePointPosition)) { this.history.addAndRedo(new DeleteConnectionHistoryItem(this.connector, this.oppositePointPosition)); this.history.addAndRedo(new AddConnectionHistoryItem(this.connector, this.oppositeItem, pointIndex, this.oppositePointPosition)); } } onFinishWithChanges(): void { ModelUtils.updateConnectorContainer(this.history, this.model, this.connector); ModelUtils.deleteConnectorUnnecessaryPoints(this.history, this.connector); this.handler.tryUpdateModelSize(); } getDraggingElementKeys(): ItemKey[] { return this.connector ? [this.connector.key] : []; } private getOppositePointPosition() { return this.pointPosition === ConnectorPosition.Begin ? ConnectorPosition.End : ConnectorPosition.Begin; } private allowAttachToObjects(evt: DiagramMouseEvent, checkContainers: boolean, checkOppositeItem: boolean) { if(this.handler.canMultipleSelection(evt)) return false; const connector = this.connector; if(connector && evt.source.type === MouseEventElementType.Shape) { const targetItem = this.model.findItem(evt.source.key); if(checkContainers && this.model.findItemContainerCore(connector, c => c === targetItem)) return false; if(checkContainers && this.oppositeItem && this.model.findItemContainerCore(this.oppositeItem, c => c === targetItem)) return false; if(checkOppositeItem && this.oppositeItem === targetItem && this.oppositeConnectionPointIndex === -1) return false; } return true; } onConnectionPointsShow(key: string, points: ConnectionPointInfo[]): void { if(this.connector && this.pointPosition !== undefined && (this.connector.endItem && this.connector.endItem.key === key || this.connector.beginItem && this.connector.beginItem.key === key)) { const position = this.connector.beginItem && this.connector.beginItem.key === key ? ConnectorPosition.Begin : ConnectorPosition.End; points.forEach((point, index) => { point.allowed = this.handler.canPerformChangeConnectionOnUpdateUI( this.connector, { item: this.connector.getExtremeItem(position), position: position, connectionPointIndex: index } ); }); } } onConnectionTargetShow(key: string, info: ConnectionTargetInfo): void { if(this.connector && this.pointPosition !== undefined && (this.connector.endItem && this.connector.endItem.key === key || this.connector.beginItem && this.connector.beginItem.key === key)) { const position = this.connector.beginItem && this.connector.beginItem.key === key ? ConnectorPosition.Begin : ConnectorPosition.End; info.allowed = this.handler.canPerformChangeConnectionOnUpdateUI( this.connector, { item: this.connector.getExtremeItem(position), position: position, connectionPointIndex: -1 } ); } } }