UNPKG

devexpress-diagram

Version:

DevExpress Diagram Control

109 lines (96 loc) 5.26 kB
import { ShapeDescription } from "./ShapeDescription"; import { SvgPrimitive } from "../../../Render/Primitives/Primitive"; 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 { Shape } from "../Shape"; import { UnitConverter } from "@devexpress/utils/lib/class/unit-converter"; import { ImagePrimitive } from "../../../Render/Primitives/ImagePrimitive"; import { RectanglePrimitive } from "../../../Render/Primitives/RectaglePrimitive"; import { GroupPrimitive } from "../../../Render/Primitives/GroupPrimitive"; import { RenderUtils } from "../../../Render/Utils"; import { ClipPathPrimitive } from "../../../Render/Primitives/ClipPathPrimitive"; import { ShapeImageIndicator } from "../../../Render/ShapeImageIndicator"; export const ShapeDefaultDimension = 1440; export const ShapeDefaultSize = new Size(ShapeDefaultDimension, ShapeDefaultDimension); export const SHAPE_IMAGE_CLASSNAMES = { IMAGE: "dxdi-image", IMAGE_PLACEHOLDER: "dxdi-image-placeholder", LOADING_INDICATOR: "dxdi-spinner", USER_PIC: "dxdi-user", WARNING_MARK: "dxdi-warning" }; export abstract class ShapeWithImageDescription extends ShapeDescription { static readonly imageScalingRule = "xMidYMid meet"; protected readonly defaultIconSize = 480; constructor(defaultSize: Size = ShapeDefaultSize.clone(), protected hasDefaultText?: boolean) { super(defaultSize, hasDefaultText); } get enableImage() { return true; } protected getImageMargin(forToolbox: boolean) { return forToolbox ? UnitConverter.pixelsToTwips(2) : UnitConverter.pixelsToTwips(3); } createImagePrimitives(shape: Shape, forToolbox: boolean): SvgPrimitive<SVGGraphicsElement>[] { if(!this.enableImage) return []; const rect = this.getImagePlacementRectangle(shape.rectangle, forToolbox); if(forToolbox) return this.createImagePlaceholder(rect); let imagePrimitives = []; if(shape.image.isEmpty || shape.image.unableToLoad) imagePrimitives = imagePrimitives.concat(this.createEmptyImagePrimitives(rect, shape.image.unableToLoad)); else if(shape.image.renderUrl === "") imagePrimitives = imagePrimitives.concat(this.createLoadingImagePrimitives(rect)); else imagePrimitives = imagePrimitives.concat(this.createLoadedImagePrimitives(rect, shape.image.renderUrl)); if(shape.image.renderUrl === "") { const clipPathId = RenderUtils.generateSvgElementId("clipImage"); return [].concat([ new GroupPrimitive(imagePrimitives, SHAPE_IMAGE_CLASSNAMES.IMAGE, undefined, clipPathId), new ClipPathPrimitive(clipPathId, [ new RectanglePrimitive(rect.x, rect.y, rect.width, rect.height) ] ) ]); } else return imagePrimitives; } createImagePlaceholder(rect: Rectangle): SvgPrimitive<SVGGraphicsElement>[] { return []; } createLoadedImagePrimitives(rect: Rectangle, imageUrl: string): SvgPrimitive<SVGGraphicsElement>[] { return [ new ImagePrimitive(rect.x, rect.y, rect.width, rect.height, imageUrl, ShapeWithImageDescription.imageScalingRule, undefined, SHAPE_IMAGE_CLASSNAMES.IMAGE) ]; } createLoadingImagePrimitives(rect: Rectangle): SvgPrimitive<SVGGraphicsElement>[] { const loadingRect = this.getIconPlacementRectangle(rect); return [ ShapeImageIndicator.createLoadingIndicatorPrimitives(loadingRect.x, loadingRect.y, this.defaultIconSize, UnitConverter.pixelsToTwips(5), SHAPE_IMAGE_CLASSNAMES.LOADING_INDICATOR) ]; } createEmptyImagePrimitives(rect: Rectangle, showWarning?: boolean): SvgPrimitive<SVGGraphicsElement>[] { const loadingRect = this.getIconPlacementRectangle(rect); let primitives: SvgPrimitive<SVGGraphicsElement>[] = []; primitives = primitives.concat( this.createEmptyImagePrimitive(loadingRect)); if(showWarning) primitives = primitives.concat(this.createWarningPrimitive(loadingRect)); return primitives; } createEmptyImagePrimitive(rect: Rectangle): GroupPrimitive { return new GroupPrimitive([]); } createWarningPrimitive(rect: Rectangle): GroupPrimitive { return new GroupPrimitive([]); } getIconPlacementRectangle(rect: Rectangle): Rectangle { const iconRect = Rectangle.fromGeometry(new Point(rect.x, rect.y), new Size(this.defaultIconSize, this.defaultIconSize)); if(iconRect.width < rect.width) iconRect.x = rect.x + (rect.width - iconRect.width) / 2; if(iconRect.height < rect.height) iconRect.y = rect.y + (rect.height - iconRect.height) / 2; return iconRect; } abstract getImagePlacementRectangle(rect: Rectangle, forToolbox?: boolean): Rectangle; abstract getImageSize(shapeSize: Size, includeMargins: boolean, forToolbox?: boolean): Size; }