UNPKG

devexpress-diagram

Version:

DevExpress Diagram Control

138 lines (124 loc) 5.56 kB
import { INativeActionListener } from "./INativeActionListener"; import { EventDispatcher } from "../Utils"; import { BatchUpdatableObject } from "@devexpress/utils/lib/class/batch-updatable"; import { DiagramModel } from "../Model/Model"; import { Selection, ISelectionChangesListener } from "../Selection/Selection"; import { DiagramMouseEvent, MouseEventElementType } from "../Events/Event"; import { INativeConnector, INativeItem, INativeShape } from "./INativeItem"; import { IToolboxDragListener } from "../Render/Toolbox/Toolbox"; import { DiagramItem } from "../Model/DiagramItem"; import { DataSource } from "../Data/DataSource"; import { ModelUtils } from "../Model/ModelUtils"; import { Point, Size } from ".."; import { Connector } from "../Model/Connectors/Connector"; import { Shape } from "../Model/Shapes/Shape"; export interface IApiController { createNativeItem(item: DiagramItem): INativeItem; createNativeShape(shape: Shape): INativeShape; createNativeConnector(connector: Connector): INativeConnector; convertPoint(point: Point): Point; convertSize(size: Size): Size; convertUnit(value: number): number; } export class ApiController extends BatchUpdatableObject implements ISelectionChangesListener, IToolboxDragListener, IApiController { private events: EventDispatcher<INativeActionListener>; model: DiagramModel; private selection: Selection; private dataSource: DataSource; constructor(events: EventDispatcher<INativeActionListener>, selection: Selection, model: DiagramModel) { super(); this.events = events; this.model = model; this.selection = selection; } notifySelectionChanged(selection: Selection): void { if(this.isUpdateLocked()) this.registerOccurredEvent(ApiControllerAction.SelectionChanged); else this.raiseSelectionChanged(); } notifyToolboxDragStart(): void { this.events.raise("notifyToolboxItemDragStart"); } notifyToolboxDragEnd(): void { this.events.raise("notifyToolboxItemDragEnd"); } notifyToolboxDraggingMouseMove(): void { } notifyClick(evt: DiagramMouseEvent): void { this.tryRaiseUserAction(evt, (i) => this.events.raise("notifyItemClick", i)); } notifyDblClick(evt: DiagramMouseEvent): void { this.tryRaiseUserAction(evt, (i) => this.events.raise("notifyItemDblClick", i)); } createNativeItem(item: DiagramItem): INativeItem { return item && this.cleanupNativeItem(item.toNative(this.model.units)); } createNativeShape(shape: Shape): INativeShape { return <INativeShape> this.createNativeItem(shape); } createNativeConnector(connector: Connector): INativeConnector { return <INativeConnector> this.createNativeItem(connector); } convertUnit(value: number): number { return ModelUtils.getlUnitValue(this.model.units, value); } convertPoint(point: Point): Point { return new Point( this.convertUnit(point.x), this.convertUnit(point.y) ); } convertSize(size: Size): Size { return new Size( this.convertUnit(size.width), this.convertUnit(size.height) ); } private cleanupNativeItem(item: INativeItem) { const ds = this.dataSource; if(ds) { if(ds.isAutoGeneratedKey((<INativeConnector>item).fromKey)) (<INativeConnector>item).fromKey = undefined; if(ds.isAutoGeneratedKey(item.key)) item.key = undefined; if(ds.isAutoGeneratedKey((<INativeConnector>item).toKey)) (<INativeConnector>item).toKey = undefined; } return item; } setDataSource(dataSource?: DataSource) { this.dataSource = dataSource; } private tryRaiseUserAction(evt: DiagramMouseEvent, callEvent: (item: INativeItem) => void) { if(this.isUserAction(evt)) { const item = this.model.findItem(evt.source.key); item && this.events.raise1(l => callEvent(this.createNativeItem(item))); } } private isUserAction(evt: DiagramMouseEvent): boolean { return evt.source && ( evt.source.type === MouseEventElementType.Shape || evt.source.type === MouseEventElementType.ShapeExpandButton || evt.source.type === MouseEventElementType.ShapeParameterBox || evt.source.type === MouseEventElementType.ShapeResizeBox || evt.source.type === MouseEventElementType.ShapeConnectionPoint || evt.source.type === MouseEventElementType.Connector || evt.source.type === MouseEventElementType.ConnectorPoint || evt.source.type === MouseEventElementType.ConnectorSide || evt.source.type === MouseEventElementType.ConnectorOrthogonalSide || evt.source.type === MouseEventElementType.ConnectorText ); } onUpdateUnlocked(occurredEvents: number) { if(occurredEvents & ApiControllerAction.SelectionChanged) this.raiseSelectionChanged(); } private raiseSelectionChanged() { const items = this.selection.getKeys().map(key => this.createNativeItem(this.model.findItem(key))); this.events.raise1(l => l.notifySelectionChanged(items)); } } enum ApiControllerAction { SelectionChanged = 1 << 0, }