diff --git a/frontend/webEditor/src/diagram/di.config.ts b/frontend/webEditor/src/diagram/di.config.ts index 358fc9fa..8430010d 100644 --- a/frontend/webEditor/src/diagram/di.config.ts +++ b/frontend/webEditor/src/diagram/di.config.ts @@ -22,7 +22,7 @@ import { FunctionNodeImpl, FunctionNodeView } from "./nodes/DfdFunctionNode"; import { IONodeImpl, IONodeView } from "./nodes/DfdIONode"; import "./style.css"; import { DfdPositionalLabelView } from "./labels/DfdPositionalLabel"; -import { DfdNodeLabelRenderer } from "./nodes/DfdNodeLabels"; +import { DfdNodeLabelRenderer, DfdNodeLabelSizeCalculator } from "./nodes/DfdNodeLabels"; import { FilledBackgroundLabelView } from "./labels/FilledBackgroundLabel"; import { DfdEditLabelValidatorDecorator } from "./labels/EditLabelDecorator"; import { DfdEditLabelValidator } from "./labels/EditLabelValidator"; @@ -77,5 +77,6 @@ export const diagramModule = new ContainerModule((bind, unbind, isBound, rebind) enable: [editLabelFeature], }); + bind(DfdNodeLabelSizeCalculator).toSelf().inSingletonScope(); bind(DfdNodeLabelRenderer).toSelf().inSingletonScope(); }); diff --git a/frontend/webEditor/src/diagram/nodes/DfdNodeLabels.tsx b/frontend/webEditor/src/diagram/nodes/DfdNodeLabels.tsx index fef034de..1c31a8fe 100644 --- a/frontend/webEditor/src/diagram/nodes/DfdNodeLabels.tsx +++ b/frontend/webEditor/src/diagram/nodes/DfdNodeLabels.tsx @@ -10,18 +10,16 @@ import { ContainsDfdLabels } from "../../labels/feature"; import { RemoveLabelAssignmentAction } from "../../labels/assignmentCommand"; @injectable() -export class DfdNodeLabelRenderer { +export class DfdNodeLabelSizeCalculator { static readonly LABEL_HEIGHT = 10; static readonly LABEL_SPACE_BETWEEN = 2; - static readonly LABEL_SPACING_HEIGHT = DfdNodeLabelRenderer.LABEL_HEIGHT + DfdNodeLabelRenderer.LABEL_SPACE_BETWEEN; + static readonly LABEL_SPACING_HEIGHT = + DfdNodeLabelSizeCalculator.LABEL_HEIGHT + DfdNodeLabelSizeCalculator.LABEL_SPACE_BETWEEN; static readonly LABEL_TEXT_PADDING = 8; - constructor( - @inject(TYPES.IActionDispatcher) private readonly actionDispatcher: IActionDispatcher, - @inject(LabelTypeRegistry) private readonly labelTypeRegistry: LabelTypeRegistry, - ) {} + constructor(@inject(LabelTypeRegistry) private readonly labelTypeRegistry: LabelTypeRegistry) {} - private getLabel(label: LabelAssignment): { type: LabelType; value: LabelTypeValue } | undefined { + protected getLabel(label: LabelAssignment): { type: LabelType; value: LabelTypeValue } | undefined { const labelType = this.labelTypeRegistry.getLabelType(label.labelTypeId); const labelTypeValue = labelType?.values.find((value) => value.id === label.labelTypeValueId); if (!labelType || !labelTypeValue) { @@ -45,10 +43,20 @@ export class DfdNodeLabelRenderer { } const text = `${label.type.name}: ${label.value.text}`; - const width = calculateTextSize(text, "5pt sans-serif").width + DfdNodeLabelRenderer.LABEL_TEXT_PADDING; + const width = calculateTextSize(text, "5pt sans-serif").width + DfdNodeLabelSizeCalculator.LABEL_TEXT_PADDING; return [text, width]; } +} + +@injectable() +export class DfdNodeLabelRenderer extends DfdNodeLabelSizeCalculator { + constructor( + @inject(TYPES.IActionDispatcher) private readonly actionDispatcher: IActionDispatcher, + @inject(LabelTypeRegistry) labelTypeRegistry: LabelTypeRegistry, + ) { + super(labelTypeRegistry); + } renderSingleNodeLabel(node: ContainsDfdLabels & SNodeImpl, label: LabelAssignment, x: number, y: number): VNode { const [text, width] = this.computeLabelContent(label); diff --git a/frontend/webEditor/src/diagram/nodes/common.ts b/frontend/webEditor/src/diagram/nodes/common.ts index b49ba37c..f23077b6 100644 --- a/frontend/webEditor/src/diagram/nodes/common.ts +++ b/frontend/webEditor/src/diagram/nodes/common.ts @@ -6,8 +6,7 @@ import { calculateTextSize } from "../../utils/TextSize"; import { ArrowEdgeImpl } from "../edges/ArrowEdge"; import { VNodeStyle } from "snabbdom"; import { DfdInputPortImpl } from "../ports/DfdInputPort"; -import { inject } from "inversify"; -import { DfdNodeLabelRenderer } from "./DfdNodeLabels"; +import { DfdNodeLabelSizeCalculator } from "./DfdNodeLabels"; import { containsDfdLabelFeature } from "../../labels/feature"; export interface DfdNode extends SNode { @@ -23,7 +22,7 @@ export abstract class DfdNodeImpl extends SNodeImpl implements WithEditableLabel static readonly WIDTH_PADDING = 12; static readonly NODE_COLOR = "var(--color-primary)"; static readonly HIGHLIGHTED_COLOR = "var(--color-highlighted)"; - @inject(DfdNodeLabelRenderer) private readonly dfdNodeLabelRenderer?: DfdNodeLabelRenderer; + dfdNodeLabelRenderer?: DfdNodeLabelSizeCalculator; text: string = ""; color?: string; labels: LabelAssignment[] = []; @@ -63,8 +62,8 @@ export abstract class DfdNodeImpl extends SNodeImpl implements WithEditableLabel if (hasLabels && !this.hideLabels) { return ( this.labelStartHeight() + - this.labels.length * DfdNodeLabelRenderer.LABEL_SPACING_HEIGHT + - DfdNodeLabelRenderer.LABEL_SPACE_BETWEEN + this.labels.length * DfdNodeLabelSizeCalculator.LABEL_SPACING_HEIGHT + + DfdNodeLabelSizeCalculator.LABEL_SPACE_BETWEEN ); } else { return this.noLabelHeight(); diff --git a/frontend/webEditor/src/labels/feature.ts b/frontend/webEditor/src/labels/feature.ts index 2cf25d0f..df27df4e 100644 --- a/frontend/webEditor/src/labels/feature.ts +++ b/frontend/webEditor/src/labels/feature.ts @@ -1,10 +1,12 @@ import { SModelElementImpl } from "sprotty"; import { LabelAssignment } from "./LabelType"; +import { DfdNodeLabelSizeCalculator } from "../diagram/nodes/DfdNodeLabels"; export const containsDfdLabelFeature = Symbol("dfd-label-feature"); export interface ContainsDfdLabels extends SModelElementImpl { labels: LabelAssignment[]; + dfdNodeLabelRenderer?: DfdNodeLabelSizeCalculator; } export function containsDfdLabels(element: T): element is T & ContainsDfdLabels { diff --git a/frontend/webEditor/src/serialize/ModelFactory.ts b/frontend/webEditor/src/serialize/ModelFactory.ts index 3947605a..a330c393 100644 --- a/frontend/webEditor/src/serialize/ModelFactory.ts +++ b/frontend/webEditor/src/serialize/ModelFactory.ts @@ -1,11 +1,15 @@ -import { injectable } from "inversify"; +import { inject, injectable } from "inversify"; import { SChildElementImpl, SModelElementImpl, SModelFactory, SParentElementImpl } from "sprotty"; import { DfdNode } from "../diagram/nodes/common"; import { getBasicType, SLabel, SModelElement } from "sprotty-protocol"; import { ArrowEdge } from "../diagram/edges/ArrowEdge"; +import { containsDfdLabels } from "../labels/feature"; +import { DfdNodeLabelSizeCalculator } from "../diagram/nodes/DfdNodeLabels"; @injectable() export class DfdModelFactory extends SModelFactory { + @inject(DfdNodeLabelSizeCalculator) dfdNodeLabelRenderer?: DfdNodeLabelSizeCalculator; + override createElement(schema: SModelElement | SModelElementImpl, parent?: SParentElementImpl): SChildElementImpl { if (schema instanceof SModelElementImpl) { return super.createElement(schema, parent); @@ -47,6 +51,9 @@ export class DfdModelFactory extends SModelFactory { if (element.features === undefined) { element.features = new Set(); } + if (containsDfdLabels(element)) { + element.dfdNodeLabelRenderer = this.dfdNodeLabelRenderer; + } return element; }