UNPKG

theia-sprotty

Version:

Glue code for sprotty diagrams in a Theia IDE

121 lines (103 loc) 5.14 kB
/* * Copyright (C) 2017 TypeFox and others. * * Licensed under the Apache License, Version 2.0 (the "License") you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 */ import { TheiaDiagramServer } from '../sprotty/theia-diagram-server'; import { TheiaSprottyConnector } from '../sprotty/theia-sprotty-connector' import { DiagramConfigurationRegistry } from './diagram-configuration' import { injectable, inject } from "inversify" import { OpenerOptions, OpenHandler, FrontendApplicationContribution, ApplicationShell } from "@theia/core/lib/browser" import URI from "@theia/core/lib/common/uri" import { DiagramWidget, DiagramWidgetFactory } from "./diagram-widget" import { DiagramWidgetRegistry } from "./diagram-widget-registry" import { Emitter, Event, SelectionService } from '@theia/core/lib/common' import { TYPES, ModelSource, IActionDispatcher, DiagramServer } from 'sprotty/lib' import { EditorManager } from '@theia/editor/lib/browser'; export const DiagramManagerProvider = Symbol('DiagramManagerProvider') export type DiagramManagerProvider = () => Promise<DiagramManager> export interface DiagramManager extends OpenHandler, FrontendApplicationContribution { readonly diagramType: string readonly onDiagramOpened: Event<URI> } @injectable() export abstract class DiagramManagerImpl implements DiagramManager { @inject(ApplicationShell) protected readonly shell: ApplicationShell @inject(DiagramWidgetRegistry) protected readonly widgetRegistry: DiagramWidgetRegistry @inject(SelectionService) protected readonly selectionService: SelectionService @inject(DiagramConfigurationRegistry) protected diagramConfigurationRegistry: DiagramConfigurationRegistry @inject(EditorManager) protected editorManager: EditorManager protected readonly onDiagramOpenedEmitter = new Emitter<URI>() abstract get diagramType(): string abstract iconClass: string get id() { return this.diagramType + "-diagram-opener" } get onDiagramOpened(): Event<URI> { return this.onDiagramOpenedEmitter.event } canHandle(uri: URI, options?: OpenerOptions | undefined): number { return 10 } open(uri: URI, input?: OpenerOptions): Promise<DiagramWidget> { const promiseDiagramWidget = this.getOrCreateDiagramWidget(uri) promiseDiagramWidget.then(diagramWidget => { window.requestAnimationFrame(() => { this.shell.activateWidget(diagramWidget.id) this.onDiagramOpenedEmitter.fire(uri) }) }) return promiseDiagramWidget } protected async getOrCreateDiagramWidget(uri: URI): Promise<DiagramWidget> { const widget = await this.widgetRegistry.getWidget(uri, this.diagramType) if (widget !== undefined) return widget const newWidget = this.createDiagramWidget(uri) this.addToShell(newWidget) return Promise.resolve(newWidget) } protected createDiagramWidget(uri: URI): DiagramWidget { const widgetId = this.widgetRegistry.nextId() const svgContainerId = widgetId + '_sprotty' const diagramConfiguration = this.diagramConfigurationRegistry.get(this.diagramType) const diContainer = diagramConfiguration.createContainer(svgContainerId) const modelSource = diContainer.get<ModelSource>(TYPES.ModelSource) if (modelSource instanceof DiagramServer) modelSource.clientId = widgetId if (modelSource instanceof TheiaDiagramServer && this.diagramConnector) this.diagramConnector.connect(modelSource) const newWidget = this.diagramWidgetFactory({ id: widgetId, svgContainerId, uri, diagramType: this.diagramType, modelSource, actionDispatcher: diContainer.get<IActionDispatcher>(TYPES.IActionDispatcher) }) newWidget.title.closable = true newWidget.title.label = uri.path.base newWidget.title.icon = this.iconClass this.widgetRegistry.addWidget(uri, this.diagramType, newWidget) newWidget.disposed.connect(() => { this.widgetRegistry.removeWidget(uri, this.diagramType) if (modelSource instanceof TheiaDiagramServer && this.diagramConnector) this.diagramConnector.disconnect(modelSource) }) return newWidget } protected addToShell(widget: DiagramWidget): void { const currentEditor = this.editorManager.currentEditor const options: ApplicationShell.WidgetOptions = { area: 'main' } if (!!currentEditor && currentEditor.editor.uri.toString(true) === widget.uri.toString(true)) { options.ref = currentEditor options.mode = 'split-right' } this.shell.addWidget(widget, options) } protected get diagramWidgetFactory(): DiagramWidgetFactory { return options => new DiagramWidget(options) } get diagramConnector(): TheiaSprottyConnector | undefined { return undefined } }