UNPKG

devexpress-diagram

Version:

DevExpress Diagram Control

177 lines (157 loc) 7.16 kB
import { UnitConverter } from "@devexpress/utils/lib/class/unit-converter"; import { Size } from "@devexpress/utils/lib/geometry/size"; import { DiagramLocalizationService } from "../../../LocalizationService"; import { TextOwner } from "../../../Render/Measurer/ITextMeasurer"; import { SvgPrimitive } from "../../../Render/Primitives/Primitive"; import { RectanglePrimitive } from "../../../Render/Primitives/RectaglePrimitive"; import { TextAngle, TextPrimitive } from "../../../Render/Primitives/TextPrimitive"; import { EventDispatcher } from "../../../Utils"; import { Rectangle } from "@devexpress/utils/lib/geometry/rectangle"; import { ConnectionPoint } from "../../ConnectionPoint"; import { ConnectionPointSide, DiagramItem } from "../../DiagramItem"; import { Shape } from "../Shape"; import { ShapeParameterPoint } from "../ShapeParameterPoint"; import { ShapeParameters } from "../ShapeParameters"; import { Point } from "@devexpress/utils/lib/geometry/point"; export const ShapeDefaultDimension = 1440; export const ShapeMinDimension = 360; export const ShapeDefaultSize = new Size(ShapeDefaultDimension, ShapeDefaultDimension); export const ShapeTextPadding = UnitConverter.pixelsToTwips(10); export abstract class ShapeDescription { protected connectionPoints: ConnectionPoint[]; protected connectionPointsWhileSelected: ConnectionPoint[]; static readonly textSpacing = UnitConverter.pixelsToTwips(2); onChanged: EventDispatcher<IShapeDescriptionChangesListener> = new EventDispatcher(); constructor(public defaultSize: Size = ShapeDefaultSize.clone(), protected hasDefaultText?: boolean) { this.connectionPoints = this.createConnectionPoints(); } abstract get key(): string; get enableText() { return true; } get allowEditText() { return true; } get enableImage() { return false; } get allowEditImage() { return true; } get hasTemplate() { return false; } get enableChildren() { return false; } get minWidth() { return undefined; } get minHeight() { return undefined; } get maxWidth() { return undefined; } get maxHeight() { return undefined; } get toolboxSize() { return this.defaultSize; } abstract get keepRatioOnAutoSize(): boolean; getTitle() { return DiagramLocalizationService.shapeTexts[this.key]; } getDefaultText() { return this.hasDefaultText ? DiagramLocalizationService.shapeTexts[this.key] : ""; } getDefaultImageUrl() { return ""; } getConnectionPoints(): ConnectionPoint[] { return this.connectionPoints; } protected createConnectionPoints(): ConnectionPoint[] { return [ new ConnectionPoint(0.5, 0, ConnectionPointSide.North), new ConnectionPoint(1, 0.5, ConnectionPointSide.East), new ConnectionPoint(0.5, 1, ConnectionPointSide.South), new ConnectionPoint(0, 0.5, ConnectionPointSide.West) ]; } processConnectionPoint(shape: Shape, point: ConnectionPoint) { } getConnectionPointIndexForItem(item: DiagramItem, connectionPointIndex: number): number { return connectionPointIndex; } getConnectionPointIndexForSide(side: ConnectionPointSide): number { return side; } static getConnectionPointSideByGeometry(point: Point): ConnectionPointSide { if(point.x >= point.y && (point.x > 0 || point.y > 0)) { if(point.x < 0.5 || (1 - point.x) >= point.y) return ConnectionPointSide.North; return ConnectionPointSide.East; } else { if(point.x > 0.5 || (1 - point.x) <= point.y) return ConnectionPointSide.South; return ConnectionPointSide.West; } } createParameters(parameters: ShapeParameters) { } normalizeParameters(shape: Shape, parameters: ShapeParameters) { } modifyParameters(shape: Shape, parameters: ShapeParameters, deltaX: number, deltaY: number) { throw Error("Not implemented"); } changeParameterValue(parameters: ShapeParameters, key: string, change: (p) => number) { const p = parameters.get(key); p.value = change(p); } getParameterPoints(shape: Shape): ShapeParameterPoint[] { return []; } getExpandedSize(shape: Shape): Size { return shape.size; } getCollapsedSize(shape: Shape): Size { return shape.size; } getToolboxHeightToWidthRatio(width: number, height: number): number { return height / width; } allowResizeHorizontally(_shape: Shape): boolean { return true; } allowResizeVertically(_shape: Shape): boolean { return true; } createPrimitives(shape: Shape, forToolbox?: boolean): SvgPrimitive<SVGGraphicsElement>[] { let primitives: SvgPrimitive<SVGGraphicsElement>[] = []; primitives = primitives.concat(this.createShapePrimitives(shape, forToolbox)); if(this.enableImage) primitives = primitives.concat(this.createImagePrimitives(shape, forToolbox)); if(this.enableText) primitives = primitives.concat(this.createTextPrimitives(shape, forToolbox)); return primitives; } abstract createShapePrimitives(shape: Shape, forToolbox?: boolean): SvgPrimitive<SVGGraphicsElement>[]; createImagePrimitives(_shape: Shape, _forToolbox: boolean): SvgPrimitive<SVGGraphicsElement>[] { return []; } createTextPrimitives(shape: Shape, forToolbox?: boolean): SvgPrimitive<SVGGraphicsElement>[] { if(shape.text === undefined || shape.text === "") return []; const rect = this.getTextRectangle(shape); return [ new TextPrimitive(rect.x, rect.y, shape.text, TextOwner.Shape, rect.width, rect.height, ShapeDescription.textSpacing, shape.styleText, false, this.getTextClipPathId(forToolbox), undefined, this.getTextAngle() ) ]; } getTextClipPathId(_forToolbox?: boolean): string { return undefined; } getTextAngle(): TextAngle { return TextAngle.Angle0deg; } getClientRectangle(shape: Shape): Rectangle { return shape.rectangle; } getTextEditRectangle(shape: Shape): Rectangle { return this.getTextRectangle(shape); } createSelectorPrimitives(shape: Shape): SvgPrimitive<SVGGraphicsElement>[] { return [ new RectanglePrimitive(shape.position.x, shape.position.y, shape.size.width, shape.size.height, null, "selector") ]; } protected raiseShapeDescriptionChanged(description: ShapeDescription): void { this.onChanged.raise1(l => l.notifyShapeDescriptionChanged(description)); } abstract getTextRectangle(shape: Shape): Rectangle; abstract getSizeByText(textSize: Size, shape: Shape): Size; } export interface IShapeDescriptionChangesListener { notifyShapeDescriptionChanged(description: ShapeDescription); }