devexpress-diagram
Version:
DevExpress Diagram Control
183 lines (165 loc) • 7.5 kB
text/typescript
import { Rectangle } from "@devexpress/utils/lib/geometry/rectangle";
import { Size } from "@devexpress/utils/lib/geometry/size";
import { Point } from "@devexpress/utils/lib/geometry/point";
import { SvgPrimitive } from "../../Render/Primitives/Primitive";
import { ShapeDescription, ShapeMinDimension } from "./Descriptions/ShapeDescription";
import { ShapeParameters } from "./ShapeParameters";
import { DiagramItem, ConnectionPointSide } from "../DiagramItem";
import { ConnectionPoint } from "../ConnectionPoint";
import { ImageInfo } from "../../Images/ImageInfo";
import { INativeShape } from "../../Api/INativeItem";
import { NativeShape } from "../../Api/NativeItem";
import { TextAngle } from "../../Render/Primitives/TextPrimitive";
import { DiagramUnit } from "../..";
export class Shape extends DiagramItem {
position: Point;
size: Size;
text: string;
image: ImageInfo;
parameters: ShapeParameters;
children: DiagramItem[] = [];
expanded: boolean = true;
expandedSize: Size = undefined;
constructor(public description: ShapeDescription, position: Point, forToolbox?: boolean) {
super();
if(!description)
throw Error("Shape type is incorrect");
this.position = position.clone();
const defaultSize = forToolbox ? description.toolboxSize : description.defaultSize;
this.size = defaultSize.clone();
this.text = description.getDefaultText();
this.image = new ImageInfo(description.getDefaultImageUrl());
this.parameters = new ShapeParameters();
description.createParameters(this.parameters);
}
assign(item: Shape) {
super.assign(item);
item.size = this.size.clone();
item.text = this.text;
item.image = this.image.clone();
item.parameters = this.parameters.clone();
item.children = this.children.slice();
item.expanded = this.expanded;
if(this.expandedSize)
item.expandedSize = this.expandedSize.clone();
}
clone() {
const clone = new Shape(this.description, this.position.clone());
this.assign(clone);
return clone;
}
get enableText() { return this.description.enableText; }
get allowEditText() { return this.description.allowEditText; }
get hasTemplate() { return this.description.hasTemplate; }
get enableChildren() { return this.description.enableChildren; }
get enableImage() { return this.description.enableImage; }
get allowEditImage() { return this.description.allowEditImage; }
getMinWidth(settingsMinWidth: number | undefined) {
return typeof (this.description.minWidth) === "number" ? this.description.minWidth :
typeof (settingsMinWidth) === "number" ? settingsMinWidth : ShapeMinDimension;
}
getMinHeight(settingsMinHeight: number | undefined) {
return typeof (this.description.minHeight) === "number" ? this.description.minHeight :
typeof (settingsMinHeight) === "number" ? settingsMinHeight : ShapeMinDimension;
}
getMaxWidth(settingsMaxWidth: number | undefined) {
return typeof (this.description.maxWidth) === "number" ? this.description.maxWidth :
typeof (settingsMaxWidth) === "number" ? settingsMaxWidth : undefined;
}
getMaxHeight(settingsMaxHeight: number | undefined) {
return typeof (this.description.maxHeight) === "number" ? this.description.maxHeight :
typeof (settingsMaxHeight) === "number" ? settingsMaxHeight : undefined;
}
createPrimitives(): SvgPrimitive<SVGGraphicsElement>[] {
return this.description.createPrimitives(this);
}
createSelectorPrimitives(): SvgPrimitive<SVGGraphicsElement>[] {
return this.description.createSelectorPrimitives(this);
}
normalizeX(x: number) {
return Math.max(this.position.x, Math.min(x, this.position.x + this.size.width));
}
normalizeY(y: number) {
return Math.max(this.position.y, Math.min(y, this.position.y + this.size.height));
}
getConnectionPoints(): ConnectionPoint[] {
const result = this.description.getConnectionPoints().map(pt => {
const point = new ConnectionPoint(
this.position.x + pt.x * this.size.width,
this.position.y + pt.y * this.size.height,
pt.side
);
this.description.processConnectionPoint(this, point);
return point;
});
return result;
}
getConnectionPointSide(point: ConnectionPoint, targetPoint?: Point): ConnectionPointSide {
if(point.side !== ConnectionPointSide.Undefined)
return point.side;
return this.getConnectionPointSideByGeometry(point);
}
getConnectionPointSideByGeometry(point: Point): ConnectionPointSide {
const pt = point.clone().offset(-this.position.x, -this.position.y).multiply(1 / this.size.width, 1 / this.size.height);
return ShapeDescription.getConnectionPointSideByGeometry(pt);
}
getConnectionPointIndexForItem(item: DiagramItem, connectionPointIndex: number): number {
return this.description.getConnectionPointIndexForItem(item, connectionPointIndex);
}
getConnectionPointIndexForSide(side: ConnectionPointSide): number {
return this.description.getConnectionPointIndexForSide(side);
}
toggleExpandedSize() {
if(!this.expanded) {
this.expandedSize = this.size.clone();
this.size = this.getCollapsedSize();
}
else {
this.size = this.getExpandedSize();
this.expandedSize = undefined;
}
}
getExpandedSize(): Size {
return this.description.getExpandedSize(this);
}
getCollapsedSize(): Size {
return this.description.getCollapsedSize(this);
}
getToolboxHeightToWidthRatio(): number {
return this.description.getToolboxHeightToWidthRatio(this.size.width, this.size.height);
}
get allowResizeHorizontally() {
return this.description.allowResizeHorizontally(this);
}
get allowResizeVertically() {
return this.description.allowResizeVertically(this);
}
get rectangle(): Rectangle {
return Rectangle.fromGeometry(this.position, this.size);
}
get clientRectangle(): Rectangle {
return this.description.getClientRectangle(this);
}
get textRectangle(): Rectangle {
return this.description.getTextRectangle(this);
}
get textEditRectangle(): Rectangle {
return this.description.getTextEditRectangle(this);
}
get textAngle(): TextAngle {
return this.description.getTextAngle();
}
toNative(units?: DiagramUnit): INativeShape {
const item = new NativeShape(this.key, this.dataKey);
item.type = this.description.key;
item.text = this.text;
item.position = this.position.clone();
item.size = this.size.clone();
item.attachedConnectorIds = this.attachedConnectors.map(c => c.key);
item.applyUnits(units);
item.containerId = this.container ? this.container.key : null;
item.containerChildItemIds = this.children.map(item => item.key);
item.containerExpanded = this.expanded;
return item;
}
}