From 26982b02014151a3c6fefbbf6438777eeccf93fa Mon Sep 17 00:00:00 2001 From: Jette Petzold Date: Mon, 16 May 2022 15:36:03 +0200 Subject: [PATCH 01/80] added template panel --- language-server/src/options/actions.ts | 4 ++ language-server/src/stpa-diagramServer.ts | 8 ++- language-server/src/templates/templates.ts | 29 +++++++++++ webview/src/di.symbols.ts | 1 + webview/src/options/actions.ts | 5 +- webview/src/options/option-models.ts | 5 ++ webview/src/options/options-module.ts | 4 ++ webview/src/options/options-registry.ts | 13 ++++- webview/src/options/options-renderer.tsx | 42 ++++++++++++++- webview/src/template/template-panel.tsx | 60 ++++++++++++++++++++++ 10 files changed, 166 insertions(+), 5 deletions(-) create mode 100644 language-server/src/templates/templates.ts create mode 100644 webview/src/template/template-panel.tsx diff --git a/language-server/src/options/actions.ts b/language-server/src/options/actions.ts index 4e3e9402..05615193 100644 --- a/language-server/src/options/actions.ts +++ b/language-server/src/options/actions.ts @@ -16,12 +16,14 @@ */ import { Action } from "sprotty-protocol"; +import { Template } from "../templates/templates"; import { SynthesisOption, ValuedSynthesisOption } from "./option-models"; /** Request message from the server to update the diagram options widget on the client. */ export interface UpdateOptionsAction extends Action { kind: typeof UpdateOptionsAction.KIND valuedSynthesisOptions: ValuedSynthesisOption[] + templates: Template[] clientId: string } @@ -30,11 +32,13 @@ export namespace UpdateOptionsAction { export function create( valuedSynthesisOptions: ValuedSynthesisOption[], + templates: Template[], clientId: string, ): UpdateOptionsAction { return { kind: KIND, valuedSynthesisOptions, + templates, clientId, } } diff --git a/language-server/src/stpa-diagramServer.ts b/language-server/src/stpa-diagramServer.ts index 03fe6e72..a7fc7499 100644 --- a/language-server/src/stpa-diagramServer.ts +++ b/language-server/src/stpa-diagramServer.ts @@ -18,12 +18,14 @@ import { Action, DiagramServer, DiagramServices, JsonMap, RequestAction, RequestModelAction, ResponseAction } from 'sprotty-protocol' import { SetSynthesisOptionsAction, UpdateOptionsAction } from './options/actions' import { StpaSynthesisOptions } from './options/synthesis-options'; +import { Template, TestTemplate } from './templates/templates'; export class StpaDiagramServer extends DiagramServer { private stpaOptions: StpaSynthesisOptions; private clientId: string; private options: JsonMap | undefined; + private templates: Template[]; constructor(dispatch: (action: A) => Promise, services: DiagramServices, synthesisOptions: StpaSynthesisOptions, clientId: string, options: JsonMap | undefined) { @@ -31,6 +33,7 @@ export class StpaDiagramServer extends DiagramServer { this.stpaOptions = synthesisOptions; this.clientId = clientId; this.options = options; + this.templates = [new TestTemplate()] } accept(action: Action): Promise { @@ -52,12 +55,14 @@ export class StpaDiagramServer extends DiagramServer { } handleSetSynthesisOption(action: SetSynthesisOptionsAction): Promise { + // update syntheses options for (const option of action.options) { const opt = this.stpaOptions.getSynthesisOptions().find(synOpt => synOpt.synthesisOption.id == option.id); if (opt) { opt.currentValue = option.currentValue; } } + // request the new model const requestAction = { kind: RequestModelAction.KIND, options: this.options @@ -67,7 +72,8 @@ export class StpaDiagramServer extends DiagramServer { } protected async handleRequestModel(action: RequestModelAction): Promise { - this.dispatch({ kind: UpdateOptionsAction.KIND, valuedSynthesisOptions: this.stpaOptions.getSynthesisOptions(), clientId: this.clientId }); + // send the avaiable syntheses options to the client before handling the request model action + this.dispatch({ kind: UpdateOptionsAction.KIND, valuedSynthesisOptions: this.stpaOptions.getSynthesisOptions(), templates: this.templates, clientId: this.clientId }); super.handleRequestModel(action); } diff --git a/language-server/src/templates/templates.ts b/language-server/src/templates/templates.ts new file mode 100644 index 00000000..8772709a --- /dev/null +++ b/language-server/src/templates/templates.ts @@ -0,0 +1,29 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2022 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ + + + +export interface Template { + svg: string; + code: string; +} + + +export class TestTemplate implements Template { + svg: string = ""; + code: string = 'testString'; +} \ No newline at end of file diff --git a/webview/src/di.symbols.ts b/webview/src/di.symbols.ts index d9710ab3..1d85ffef 100644 --- a/webview/src/di.symbols.ts +++ b/webview/src/di.symbols.ts @@ -24,4 +24,5 @@ export const DISymbol = { OptionsRenderer: Symbol("OptionsRenderer"), OptionsRegistry: Symbol("OptionsRegistry"), RenderOptionsRegistry: Symbol("RenderOptionsRegistry"), + TemplateRegistry: Symbol("TemplateRegistry"), }; \ No newline at end of file diff --git a/webview/src/options/actions.ts b/webview/src/options/actions.ts index 3a6c5a9b..03e0ca54 100644 --- a/webview/src/options/actions.ts +++ b/webview/src/options/actions.ts @@ -16,7 +16,7 @@ */ import { Action } from "sprotty-protocol"; -import { SynthesisOption, ValuedSynthesisOption } from "./option-models"; +import { SynthesisOption, Template, ValuedSynthesisOption } from "./option-models"; /** Change the value of one or multiple render options. */ export interface SetRenderOptionAction extends Action { @@ -64,6 +64,7 @@ export namespace ResetRenderOptionsAction { export interface UpdateOptionsAction extends Action { kind: typeof UpdateOptionsAction.KIND valuedSynthesisOptions: ValuedSynthesisOption[] + templates: Template[] clientId: string } @@ -72,11 +73,13 @@ export namespace UpdateOptionsAction { export function create( valuedSynthesisOptions: ValuedSynthesisOption[], + templates: Template[], clientId: string, ): UpdateOptionsAction { return { kind: KIND, valuedSynthesisOptions, + templates, clientId, } } diff --git a/webview/src/options/option-models.ts b/webview/src/options/option-models.ts index 04daff62..4fff9aee 100644 --- a/webview/src/options/option-models.ts +++ b/webview/src/options/option-models.ts @@ -81,3 +81,8 @@ export interface Pair { k: K v: V } + +export interface Template { + svg: string; + code: string; +} diff --git a/webview/src/options/options-module.ts b/webview/src/options/options-module.ts index 3443ce56..886c0d90 100644 --- a/webview/src/options/options-module.ts +++ b/webview/src/options/options-module.ts @@ -24,6 +24,7 @@ import { GeneralPanel } from "./general-panel"; import { RenderOptionsRegistry } from "./render-options-registry"; import { OptionsRegistry } from "./options-registry"; import { OptionsPanel } from "./options-panel"; +import { TemplatePanel } from "../template/template-panel"; /** Module that configures option related panels and registries. */ export const optionsModule = new ContainerModule((bind, _, isBound) => { @@ -33,6 +34,9 @@ export const optionsModule = new ContainerModule((bind, _, isBound) => { bind(OptionsPanel).toSelf().inSingletonScope(); bind(DISymbol.SidebarPanel).toService(OptionsPanel); + bind(TemplatePanel).toSelf().inSingletonScope(); + bind(DISymbol.SidebarPanel).toService(TemplatePanel); + bind(DISymbol.OptionsRenderer).to(OptionsRenderer); bind(DISymbol.OptionsRegistry).to(OptionsRegistry).inSingletonScope(); bind(TYPES.IActionHandlerInitializer).toService(DISymbol.OptionsRegistry); diff --git a/webview/src/options/options-registry.ts b/webview/src/options/options-registry.ts index 676f2a39..3e020ce2 100644 --- a/webview/src/options/options-registry.ts +++ b/webview/src/options/options-registry.ts @@ -24,7 +24,7 @@ import { UpdateOptionsAction, } from "./actions"; import { - SynthesisOption, + SynthesisOption, Template, } from "./option-models"; import { vscodeApi } from 'sprotty-vscode-webview/lib/vscode-api'; @@ -39,6 +39,7 @@ export class OptionsRegistry extends Registry implements IActionHandlerInitializ private _clientId = ""; private _synthesisOptions: SynthesisOption[] = []; + private _templates: Template[] = []; get clientId(): string { return this._clientId; @@ -48,6 +49,10 @@ export class OptionsRegistry extends Registry implements IActionHandlerInitializ return this._synthesisOptions; } + get templates(): Template[] { + return this._templates; + } + /** Returns `true` when the registry contains options and is therefore not empty. */ hasOptions(): boolean { return ( @@ -55,6 +60,10 @@ export class OptionsRegistry extends Registry implements IActionHandlerInitializ ); } + hasTemplateOptions(): boolean { + return this._templates.length !== 0; + } + initialize(registry: ActionHandlerRegistry): void { registry.register(UpdateOptionsAction.KIND, this); registry.register(SetSynthesisOptionsAction.KIND, this); @@ -78,7 +87,7 @@ export class OptionsRegistry extends Registry implements IActionHandlerInitializ currentValue: valuedOption.currentValue ?? valuedOption.synthesisOption.initialValue, })); - + this._templates = action.templates; this.notifyListeners(); } diff --git a/webview/src/options/options-renderer.tsx b/webview/src/options/options-renderer.tsx index ba1e8517..12833182 100644 --- a/webview/src/options/options-renderer.tsx +++ b/webview/src/options/options-renderer.tsx @@ -32,7 +32,8 @@ import { RenderOption, RangeOption as RangeOptionData, SynthesisOption, - TransformationOptionType + TransformationOptionType, + Template } from "./option-models"; interface AllOptions { @@ -151,6 +152,45 @@ export class OptionsRenderer { ); } + renderTemplates(templates: Template[]): (VNode | "")[] | "" { + if (templates.length === 0) return ""; + + /* const test = "}} + > + return templates.map(template => + + {test} + ); */ + + //const polyline = ""; + return templates.map(template => + + ); + } + /** Renders render options that are stored in the client. */ renderRenderOptions(renderOptions: RenderOption[]): (VNode | "")[] | "" { if (renderOptions.length === 0) return ""; diff --git a/webview/src/template/template-panel.tsx b/webview/src/template/template-panel.tsx new file mode 100644 index 00000000..a0311cd6 --- /dev/null +++ b/webview/src/template/template-panel.tsx @@ -0,0 +1,60 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2022 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ + +/** @jsx html */ +import { VNode } from "snabbdom"; +import { html } from "sprotty"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { inject, injectable, postConstruct } from "inversify"; +import { SidebarPanel } from "../sidebar"; +import { DISymbol } from "../di.symbols"; +import { OptionsRenderer } from "../options/options-renderer"; +import { FeatherIcon } from "../feather-icons-snabbdom/feather-icons-snabbdom"; +import { OptionsRegistry } from "../options/options-registry"; + +/** Sidebar panel that displays server provided STPA-DSL templates. */ +@injectable() +export class TemplatePanel extends SidebarPanel { + + @inject(DISymbol.OptionsRegistry) private optionsRegistry: OptionsRegistry; + @inject(DISymbol.OptionsRenderer) private optionsRenderer: OptionsRenderer; + + @postConstruct() + init(): void { + this.optionsRegistry.onChange(() => this.update()); + } + + get id(): string { + return 'template-panel'; + } + + get title(): string { + return 'Templates'; + } + + get icon(): VNode { + return + } + + render(): VNode { + return this.optionsRegistry.hasTemplateOptions() ? ( + this.optionsRenderer.renderTemplates(this.optionsRegistry.templates) + ) : ( + No templates provided by the diagram server. + ); + } + +} \ No newline at end of file From 6f3726b02274b46ba1674cf6d7ae428b9c37ae1f Mon Sep 17 00:00:00 2001 From: Jette Petzold Date: Tue, 17 May 2022 10:37:07 +0200 Subject: [PATCH 02/80] added rendering of template (WIP) --- language-server/src/templates/templates.ts | 28 +++++++++++-- webview/src/helper-methods.ts | 2 +- webview/src/options/option-models.ts | 4 +- webview/src/options/options-renderer.tsx | 46 ++++++---------------- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/language-server/src/templates/templates.ts b/language-server/src/templates/templates.ts index 8772709a..cefb092d 100644 --- a/language-server/src/templates/templates.ts +++ b/language-server/src/templates/templates.ts @@ -15,15 +15,37 @@ * SPDX-License-Identifier: EPL-2.0 */ - +import { SGraph, SNode, SModelElement } from 'sprotty-protocol' +import { CS_NODE_TYPE } from '../stpa-model'; export interface Template { - svg: string; + svg: Readonly; code: string; } export class TestTemplate implements Template { - svg: string = ""; + svg: Readonly = { + type: 'graph', + id: 'testTemplate', + children: [ + { + type: CS_NODE_TYPE, + id: 'node1', + size: {width: 10, height: 10}, + position: {x: 0, y: 0}, + children: [] + } as SNode, + { + type: CS_NODE_TYPE, + id: 'node2', + size: {width: 10, height: 10}, + position: {x: 20, y: 0}, + children: [] + } as SNode + ] as SModelElement[], + zoom: 1, + scroll: {x:0, y:0} + } code: string = 'testString'; } \ No newline at end of file diff --git a/webview/src/helper-methods.ts b/webview/src/helper-methods.ts index b91bd357..4a4a895d 100644 --- a/webview/src/helper-methods.ts +++ b/webview/src/helper-methods.ts @@ -25,7 +25,7 @@ import { STPAAspect, STPAEdge, STPANode, STPA_NODE_TYPE } from "./STPA-model" */ export function collectAllChildren(nodes: SNode[], children: SNode[]): void { for (const node of nodes) { - if (node.children.length != 0) { + if (node.children && node.children.length != 0) { const childrenNodes = node.children.filter(child => child instanceof SNode) as SNode[] children.push(...childrenNodes) collectAllChildren(childrenNodes, children) diff --git a/webview/src/options/option-models.ts b/webview/src/options/option-models.ts index 4fff9aee..3fcdf51b 100644 --- a/webview/src/options/option-models.ts +++ b/webview/src/options/option-models.ts @@ -15,6 +15,8 @@ * SPDX-License-Identifier: EPL-2.0 */ +import { SGraph } from "sprotty-protocol"; + /** Base option that can be rendered as an ui input*/ export interface RenderOption { id: string; @@ -83,6 +85,6 @@ export interface Pair { } export interface Template { - svg: string; + svg: Readonly; code: string; } diff --git a/webview/src/options/options-renderer.tsx b/webview/src/options/options-renderer.tsx index 12833182..784e7c4c 100644 --- a/webview/src/options/options-renderer.tsx +++ b/webview/src/options/options-renderer.tsx @@ -18,7 +18,7 @@ /** @jsx html */ import { inject, injectable } from "inversify"; import { VNode } from "snabbdom"; -import { html, IActionDispatcher, TYPES } from "sprotty"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { html, IActionDispatcher, ModelRenderer, SModelElement, TYPES, ViewRegistry } from "sprotty"; // eslint-disable-line @typescript-eslint/no-unused-vars import { SetRenderOptionAction, SetSynthesisOptionsAction, @@ -45,6 +45,15 @@ interface AllOptions { export class OptionsRenderer { @inject(TYPES.IActionDispatcher) actionDispatcher: IActionDispatcher; + viewer: ViewRegistry; + renderer: ModelRenderer; + + constructor(@inject(TYPES.ViewRegistry) viewer: ViewRegistry) { + this.viewer = viewer + this.renderer = new ModelRenderer(this.viewer, "main", []); + } + + /** * Renders all diagram options that are provided by the server. This includes * at the moment only the synthesis options. @@ -154,41 +163,8 @@ export class OptionsRenderer { renderTemplates(templates: Template[]): (VNode | "")[] | "" { if (templates.length === 0) return ""; - - /* const test = "}} - > - return templates.map(template => - - {test} - ); */ - - //const polyline = ""; return templates.map(template => - - ); +
{this.renderer?.renderElement(template.svg as any as Readonly)}
); } /** Renders render options that are stored in the client. */ From 6155cc0f7ee1394bdcb35616f7d296595fd77a1a Mon Sep 17 00:00:00 2001 From: Jette Petzold Date: Tue, 17 May 2022 14:56:39 +0200 Subject: [PATCH 03/80] get correct model renderer --- language-server/src/stpa-diagramServer.ts | 16 ++++- language-server/src/templates/templates.ts | 54 ++++++++--------- webview/src/options/option-models.ts | 6 +- webview/src/options/options-module.ts | 5 +- webview/src/options/options-registry.ts | 12 +--- webview/src/options/options-renderer.tsx | 15 ++--- webview/src/template/actions.ts | 40 +++++++++++++ webview/src/template/template-panel.tsx | 11 ++-- webview/src/template/template-registry.ts | 68 ++++++++++++++++++++++ webview/src/views.tsx | 6 +- 10 files changed, 177 insertions(+), 56 deletions(-) create mode 100644 webview/src/template/actions.ts create mode 100644 webview/src/template/template-registry.ts diff --git a/language-server/src/stpa-diagramServer.ts b/language-server/src/stpa-diagramServer.ts index a7fc7499..0f526fc7 100644 --- a/language-server/src/stpa-diagramServer.ts +++ b/language-server/src/stpa-diagramServer.ts @@ -15,7 +15,7 @@ * SPDX-License-Identifier: EPL-2.0 */ -import { Action, DiagramServer, DiagramServices, JsonMap, RequestAction, RequestModelAction, ResponseAction } from 'sprotty-protocol' +import { Action, applyBounds, DiagramServer, DiagramServices, JsonMap, RequestAction, RequestModelAction, ResponseAction, RequestBoundsAction, ComputedBoundsAction } from 'sprotty-protocol' import { SetSynthesisOptionsAction, UpdateOptionsAction } from './options/actions' import { StpaSynthesisOptions } from './options/synthesis-options'; import { Template, TestTemplate } from './templates/templates'; @@ -33,7 +33,7 @@ export class StpaDiagramServer extends DiagramServer { this.stpaOptions = synthesisOptions; this.clientId = clientId; this.options = options; - this.templates = [new TestTemplate()] + this.templates = [TestTemplate] } accept(action: Action): Promise { @@ -73,6 +73,18 @@ export class StpaDiagramServer extends DiagramServer { protected async handleRequestModel(action: RequestModelAction): Promise { // send the avaiable syntheses options to the client before handling the request model action + const test =this.templates[0].graph +/* this.dispatch({ + kind: RequestBoundsAction.KIND, + newRoot: this.templates[0].graph + } as RequestBoundsAction) */ + + const request = RequestBoundsAction.create(test); + const response = await this.request(request); + applyBounds(test, response); + const newRoot = await this.layoutEngine?.layout(test); + this.templates[0].graph = newRoot! + this.dispatch({ kind: UpdateOptionsAction.KIND, valuedSynthesisOptions: this.stpaOptions.getSynthesisOptions(), templates: this.templates, clientId: this.clientId }); super.handleRequestModel(action); } diff --git a/language-server/src/templates/templates.ts b/language-server/src/templates/templates.ts index cefb092d..c710ce4a 100644 --- a/language-server/src/templates/templates.ts +++ b/language-server/src/templates/templates.ts @@ -15,37 +15,39 @@ * SPDX-License-Identifier: EPL-2.0 */ -import { SGraph, SNode, SModelElement } from 'sprotty-protocol' +import { SGraph, SModelElement } from 'sprotty-protocol' +import { CSNode } from '../STPA-interfaces'; import { CS_NODE_TYPE } from '../stpa-model'; export interface Template { - svg: Readonly; + graph: Readonly; code: string; } +const testGraph: Readonly = { + type: 'graph', + id: 'testTemplate', + children: [ + { + type: CS_NODE_TYPE, + id: 'node1', + size: {width: 10, height: 10}, + //position: {x: 0, y: 0}, + children: [] + } as CSNode, + { + type: CS_NODE_TYPE, + id: 'node2', + size: {width: 10, height: 10}, + //position: {x: 20, y: 0}, + children: [] + } as CSNode + ] as SModelElement[], + zoom: 1, + scroll: {x:0, y:0} +} as SGraph -export class TestTemplate implements Template { - svg: Readonly = { - type: 'graph', - id: 'testTemplate', - children: [ - { - type: CS_NODE_TYPE, - id: 'node1', - size: {width: 10, height: 10}, - position: {x: 0, y: 0}, - children: [] - } as SNode, - { - type: CS_NODE_TYPE, - id: 'node2', - size: {width: 10, height: 10}, - position: {x: 20, y: 0}, - children: [] - } as SNode - ] as SModelElement[], - zoom: 1, - scroll: {x:0, y:0} - } - code: string = 'testString'; +export const TestTemplate: Template = { + graph: testGraph, + code: 'testString' } \ No newline at end of file diff --git a/webview/src/options/option-models.ts b/webview/src/options/option-models.ts index 3fcdf51b..650e6df1 100644 --- a/webview/src/options/option-models.ts +++ b/webview/src/options/option-models.ts @@ -15,7 +15,7 @@ * SPDX-License-Identifier: EPL-2.0 */ -import { SGraph } from "sprotty-protocol"; +import { SModelElement } from "sprotty"; /** Base option that can be rendered as an ui input*/ export interface RenderOption { @@ -84,7 +84,7 @@ export interface Pair { v: V } -export interface Template { - svg: Readonly; +export class Template { + graph: Readonly; code: string; } diff --git a/webview/src/options/options-module.ts b/webview/src/options/options-module.ts index 886c0d90..0cb5bcc7 100644 --- a/webview/src/options/options-module.ts +++ b/webview/src/options/options-module.ts @@ -25,6 +25,7 @@ import { RenderOptionsRegistry } from "./render-options-registry"; import { OptionsRegistry } from "./options-registry"; import { OptionsPanel } from "./options-panel"; import { TemplatePanel } from "../template/template-panel"; +import { TemplateRegistry } from "../template/template-registry"; /** Module that configures option related panels and registries. */ export const optionsModule = new ContainerModule((bind, _, isBound) => { @@ -37,11 +38,13 @@ export const optionsModule = new ContainerModule((bind, _, isBound) => { bind(TemplatePanel).toSelf().inSingletonScope(); bind(DISymbol.SidebarPanel).toService(TemplatePanel); - bind(DISymbol.OptionsRenderer).to(OptionsRenderer); + bind(DISymbol.OptionsRenderer).to(OptionsRenderer).inSingletonScope(); bind(DISymbol.OptionsRegistry).to(OptionsRegistry).inSingletonScope(); bind(TYPES.IActionHandlerInitializer).toService(DISymbol.OptionsRegistry); bind(DISymbol.RenderOptionsRegistry).to(RenderOptionsRegistry).inSingletonScope(); + bind(DISymbol.TemplateRegistry).to(TemplateRegistry).inSingletonScope(); + bind(TYPES.IActionHandlerInitializer).toService(DISymbol.TemplateRegistry); const ctx = { bind, isBound }; configureActionHandler(ctx, SetRenderOptionAction.KIND, DISymbol.RenderOptionsRegistry); diff --git a/webview/src/options/options-registry.ts b/webview/src/options/options-registry.ts index 3e020ce2..675b15eb 100644 --- a/webview/src/options/options-registry.ts +++ b/webview/src/options/options-registry.ts @@ -24,7 +24,7 @@ import { UpdateOptionsAction, } from "./actions"; import { - SynthesisOption, Template, + SynthesisOption } from "./option-models"; import { vscodeApi } from 'sprotty-vscode-webview/lib/vscode-api'; @@ -39,7 +39,6 @@ export class OptionsRegistry extends Registry implements IActionHandlerInitializ private _clientId = ""; private _synthesisOptions: SynthesisOption[] = []; - private _templates: Template[] = []; get clientId(): string { return this._clientId; @@ -49,10 +48,6 @@ export class OptionsRegistry extends Registry implements IActionHandlerInitializ return this._synthesisOptions; } - get templates(): Template[] { - return this._templates; - } - /** Returns `true` when the registry contains options and is therefore not empty. */ hasOptions(): boolean { return ( @@ -60,10 +55,6 @@ export class OptionsRegistry extends Registry implements IActionHandlerInitializ ); } - hasTemplateOptions(): boolean { - return this._templates.length !== 0; - } - initialize(registry: ActionHandlerRegistry): void { registry.register(UpdateOptionsAction.KIND, this); registry.register(SetSynthesisOptionsAction.KIND, this); @@ -87,7 +78,6 @@ export class OptionsRegistry extends Registry implements IActionHandlerInitializ currentValue: valuedOption.currentValue ?? valuedOption.synthesisOption.initialValue, })); - this._templates = action.templates; this.notifyListeners(); } diff --git a/webview/src/options/options-renderer.tsx b/webview/src/options/options-renderer.tsx index 784e7c4c..2fe74373 100644 --- a/webview/src/options/options-renderer.tsx +++ b/webview/src/options/options-renderer.tsx @@ -18,7 +18,7 @@ /** @jsx html */ import { inject, injectable } from "inversify"; import { VNode } from "snabbdom"; -import { html, IActionDispatcher, ModelRenderer, SModelElement, TYPES, ViewRegistry } from "sprotty"; // eslint-disable-line @typescript-eslint/no-unused-vars +import { html, IActionDispatcher, ModelRenderer, TYPES } from "sprotty"; // eslint-disable-line @typescript-eslint/no-unused-vars import { SetRenderOptionAction, SetSynthesisOptionsAction, @@ -45,15 +45,13 @@ interface AllOptions { export class OptionsRenderer { @inject(TYPES.IActionDispatcher) actionDispatcher: IActionDispatcher; - viewer: ViewRegistry; renderer: ModelRenderer; - constructor(@inject(TYPES.ViewRegistry) viewer: ViewRegistry) { - this.viewer = viewer - this.renderer = new ModelRenderer(this.viewer, "main", []); + setRenderer(renderer: ModelRenderer) { + //this.renderer = renderer + this.renderer = new ModelRenderer(renderer.viewRegistry, renderer.targetKind, []) } - /** * Renders all diagram options that are provided by the server. This includes * at the moment only the synthesis options. @@ -163,8 +161,11 @@ export class OptionsRenderer { renderTemplates(templates: Template[]): (VNode | "")[] | "" { if (templates.length === 0) return ""; + +/* const g: SModelElement = templates[0].graph as SModelElement + g.hasFeature(Symbol('isSelectable')) */ return templates.map(template => -
{this.renderer?.renderElement(template.svg as any as Readonly)}
); +
{this.renderer?.renderElement(template.graph)}
); } /** Renders render options that are stored in the client. */ diff --git a/webview/src/template/actions.ts b/webview/src/template/actions.ts new file mode 100644 index 00000000..df3df5fb --- /dev/null +++ b/webview/src/template/actions.ts @@ -0,0 +1,40 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2022 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ + +import { Action } from "sprotty-protocol"; +import { ModelRenderer } from "sprotty" + +/** Sent from the view. */ +export interface SendModelRendererAction extends Action { + kind: typeof SendModelRendererAction.KIND + renderer: ModelRenderer +} + +export namespace SendModelRendererAction { + export const KIND = 'sendModelRendererAction' + + export function create(renderer: ModelRenderer): SendModelRendererAction { + return { + kind: KIND, + renderer + } + } + + export function isThisAction(action: Action): action is SendModelRendererAction { + return action.kind === SendModelRendererAction.KIND; + } +} \ No newline at end of file diff --git a/webview/src/template/template-panel.tsx b/webview/src/template/template-panel.tsx index a0311cd6..be00e2cd 100644 --- a/webview/src/template/template-panel.tsx +++ b/webview/src/template/template-panel.tsx @@ -23,21 +23,22 @@ import { SidebarPanel } from "../sidebar"; import { DISymbol } from "../di.symbols"; import { OptionsRenderer } from "../options/options-renderer"; import { FeatherIcon } from "../feather-icons-snabbdom/feather-icons-snabbdom"; -import { OptionsRegistry } from "../options/options-registry"; +import { TemplateRegistry } from "./template-registry"; /** Sidebar panel that displays server provided STPA-DSL templates. */ @injectable() export class TemplatePanel extends SidebarPanel { - @inject(DISymbol.OptionsRegistry) private optionsRegistry: OptionsRegistry; + @inject(DISymbol.TemplateRegistry) private tempRegistry: TemplateRegistry; @inject(DISymbol.OptionsRenderer) private optionsRenderer: OptionsRenderer; @postConstruct() init(): void { - this.optionsRegistry.onChange(() => this.update()); + this.tempRegistry.onChange(() => this.update()); } get id(): string { + console.log(this.tempRegistry); return 'template-panel'; } @@ -50,8 +51,8 @@ export class TemplatePanel extends SidebarPanel { } render(): VNode { - return this.optionsRegistry.hasTemplateOptions() ? ( - this.optionsRenderer.renderTemplates(this.optionsRegistry.templates) + return this.tempRegistry.hasTemplateOptions() ? ( + this.optionsRenderer.renderTemplates(this.tempRegistry.templates) ) : ( No templates provided by the diagram server. ); diff --git a/webview/src/template/template-registry.ts b/webview/src/template/template-registry.ts new file mode 100644 index 00000000..8e227aec --- /dev/null +++ b/webview/src/template/template-registry.ts @@ -0,0 +1,68 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2022 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ + +import { inject, injectable } from "inversify"; +import { ActionHandlerRegistry, IActionHandlerInitializer, ICommand } from "sprotty"; +import { Action } from "sprotty-protocol"; +import { Registry } from "../base/registry"; +import { DISymbol } from "../di.symbols"; +import { UpdateOptionsAction } from "../options/actions"; +import { Template } from "../options/option-models"; +import { OptionsRenderer } from "../options/options-renderer"; +import { SendModelRendererAction } from "./actions"; + +@injectable() +export class TemplateRegistry extends Registry implements IActionHandlerInitializer { + + @inject(DISymbol.OptionsRenderer) private optionsRenderer: OptionsRenderer; + + private _templates: Template[] = []; + + get templates(): Template[] { + return this._templates; + } + + hasTemplateOptions(): boolean { + return this._templates.length !== 0; + } + + initialize(registry: ActionHandlerRegistry): void { + registry.register(UpdateOptionsAction.KIND, this); + registry.register(SendModelRendererAction.KIND, this); + } + + handle(action: Action): void | Action | ICommand { + if (UpdateOptionsAction.isThisAction(action)) { + this.handleUpdateOptions(action); + } else if (SendModelRendererAction.isThisAction(action)) { + this.handleSendModelRenderer(action) + } + } + + private handleUpdateOptions(action: UpdateOptionsAction): void { + this._templates = action.templates.map