Skip to content

Commit

Permalink
Extract abstract class for context key service (#41)
Browse files Browse the repository at this point in the history
This enables custom diagram implementations to more easily
contribute custom context keys.
  • Loading branch information
planger committed Jul 17, 2020
1 parent 27081fd commit 0b7d765
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 50 deletions.
121 changes: 71 additions & 50 deletions src/browser/diagram/glsp-diagram-context-key-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { GLSP_TYPES, isDeletable, isMoveable, SModelRoot } from "@eclipse-glsp/client";
import { GLSP_TYPES, isDeletable, isMoveable, isNotUndefined, SModelElement, SModelRoot } from "@eclipse-glsp/client";
import { SelectionService } from "@eclipse-glsp/client/lib/features/select/selection-service";
import { ApplicationShell } from "@theia/core/lib/browser";
import { ContextKey, ContextKeyService } from "@theia/core/lib/browser/context-key-service";
Expand All @@ -23,7 +23,7 @@ import { isDiagramWidgetContainer } from "sprotty-theia";
import { GLSPDiagramWidget } from "./glsp-diagram-widget";

@injectable()
export class GLSPDiagramContextKeyService {
export abstract class AbstractGLSPDiagramContextKeyService {

@inject(ApplicationShell)
protected readonly shell: ApplicationShell;
Expand All @@ -37,6 +37,64 @@ export class GLSPDiagramContextKeyService {
selectionChanged: (root: Readonly<SModelRoot>, selectedElements: string[]) => this.updateSelectionContextKeys(root, selectedElements)
};

@postConstruct()
protected init(): void {
this.registerContextKeys();
this.updateContextKeys();
this.shell.activeChanged.connect(() => this.updateContextKeys());
}

protected updateContextKeys() {
if (this.currentSelectionService) {
this.currentSelectionService.deregister(this.selectionChangeListener);
}
const glspDiagramWidget = this.getDiagramWidget();
if (glspDiagramWidget) {
this.doUpdateStaticContextKeys(glspDiagramWidget);
this.currentSelectionService = this.getSelectionService(glspDiagramWidget);
this.currentSelectionService.register(this.selectionChangeListener);
this.updateSelectionContextKeys(this.currentSelectionService.getModelRoot(), Array.from(this.currentSelectionService.getSelectedElementIDs()));
} else {
this.resetContextKeys();
}
}

protected updateSelectionContextKeys(root: Readonly<SModelRoot>, selectedElementIds: string[]) {
if (selectedElementIds.length < 1) {
this.doResetSelectionContextKeys();
return;
}
this.doUpdateSelectionContextKeys(selectedElementIds.map(id => root.index.getById(id)).filter(isNotUndefined));
}

protected getSelectionService(glspDiagramWidget: GLSPDiagramWidget): SelectionService {
return glspDiagramWidget.diContainer.get(GLSP_TYPES.SelectionService);
}

protected getDiagramWidget() {
const widget = (this.shell.activeWidget || this.shell.currentWidget);
if (widget instanceof GLSPDiagramWidget) {
return widget as GLSPDiagramWidget;
} else if (isDiagramWidgetContainer(widget) && widget.diagramWidget instanceof GLSPDiagramWidget) {
return widget.diagramWidget as GLSPDiagramWidget;
}
return undefined;
}

protected resetContextKeys() {
this.doResetStaticContextKeys();
this.doResetSelectionContextKeys();
}

protected abstract registerContextKeys(): void;
protected abstract doUpdateStaticContextKeys(glspDiagramWidget: GLSPDiagramWidget): void;
protected abstract doResetStaticContextKeys(): void;
protected abstract doUpdateSelectionContextKeys(selectedElements: SModelElement[]): void;
protected abstract doResetSelectionContextKeys(): void;
}

export class GLSPDiagramContextKeyService extends AbstractGLSPDiagramContextKeyService {

protected _glspEditorFocus: ContextKey<boolean>;
get glspEditorFocus(): ContextKey<boolean> {
return this._glspEditorFocus;
Expand Down Expand Up @@ -72,13 +130,6 @@ export class GLSPDiagramContextKeyService {
return this._glspEditorHasMoveableSelection;
}

@postConstruct()
protected init(): void {
this.registerContextKeys();
this.updateContextKeys();
this.shell.activeChanged.connect(() => this.updateContextKeys());
}

protected registerContextKeys() {
this._glspEditorFocus = this.contextKeyService.createKey<boolean>('glspEditorFocus', false);
this._glspEditorDiagramType = this.contextKeyService.createKey<string>('glspEditorDiagramType', undefined);
Expand All @@ -89,28 +140,17 @@ export class GLSPDiagramContextKeyService {
this._glspEditorHasMoveableSelection = this.contextKeyService.createKey<boolean>('glspEditorHasMoveableSelection', false);
}

protected updateContextKeys() {
if (this.currentSelectionService) {
this.currentSelectionService.deregister(this.selectionChangeListener);
}
const glspDiagramWidget = this.getDiagramWidget();
if (glspDiagramWidget) {
this.glspEditorFocus.set(true);
this.glspEditorDiagramType.set(glspDiagramWidget.diagramType);
this.currentSelectionService = this.getSelectionService(glspDiagramWidget);
this.currentSelectionService.register(this.selectionChangeListener);
this.updateSelectionContextKeys(this.currentSelectionService.getModelRoot(), Array.from(this.currentSelectionService.getSelectedElementIDs()));
} else {
this.resetContextKeys();
}
protected doUpdateStaticContextKeys(glspDiagramWidget: GLSPDiagramWidget): void {
this.glspEditorFocus.set(true);
this.glspEditorDiagramType.set(glspDiagramWidget.diagramType);
}

protected updateSelectionContextKeys(root: Readonly<SModelRoot>, selectedElementIds: string[]) {
if (selectedElementIds.length < 1) {
this.resetSelectionContextKeys();
return;
}
const selectedElements = selectedElementIds.map(id => root.index.getById(id));
protected doResetStaticContextKeys(): void {
this.glspEditorFocus.reset();
this.glspEditorDiagramType.reset();
}

protected doUpdateSelectionContextKeys(selectedElements: SModelElement[]): void {
this.glspEditorHasSelection.set(true);
this.glspEditorHasMultipleSelection.set(selectedElements.length > 1);
this.glspEditorHasDeletableSelection.set(selectedElements.filter(isDeletable).length > 0);
Expand All @@ -120,31 +160,12 @@ export class GLSPDiagramContextKeyService {
}
}

protected getSelectionService(glspDiagramWidget: GLSPDiagramWidget): SelectionService {
return glspDiagramWidget.diContainer.get(GLSP_TYPES.SelectionService);
}

protected getDiagramWidget() {
const widget = (this.shell.activeWidget || this.shell.currentWidget);
if (widget instanceof GLSPDiagramWidget) {
return widget as GLSPDiagramWidget;
} else if (isDiagramWidgetContainer(widget) && widget.diagramWidget instanceof GLSPDiagramWidget) {
return widget.diagramWidget as GLSPDiagramWidget;
}
return undefined;
}

protected resetContextKeys() {
this.glspEditorFocus.reset();
this.glspEditorDiagramType.reset();
this.resetSelectionContextKeys();
}

protected resetSelectionContextKeys() {
protected doResetSelectionContextKeys(): void {
this.glspEditorHasDeletableSelection.reset();
this.glspEditorHasMoveableSelection.reset();
this.glspEditorHasMultipleSelection.reset();
this.glspEditorHasSelection.reset();
this.glspEditorHasSelectionOfType.reset();
}

}
4 changes: 4 additions & 0 deletions src/browser/diagram/glsp-diagram-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { inject, injectable, interfaces } from "inversify";
import { DiagramManager, DiagramManagerProvider, DiagramWidget, DiagramWidgetOptions } from "sprotty-theia";

import { TheiaOpenerOptionsNavigationService } from "../theia-opener-options-navigation-service";
import { GLSPDiagramContextKeyService } from "./glsp-diagram-context-key-service";
import { GLSPDiagramWidget } from "./glsp-diagram-widget";
import { GLSPTheiaSprottyConnector } from "./glsp-theia-sprotty-connector";

Expand All @@ -51,6 +52,9 @@ export abstract class GLSPDiagramManager extends DiagramManager {
@inject(TheiaOpenerOptionsNavigationService)
protected readonly diagramNavigationService: TheiaOpenerOptionsNavigationService;

@inject(GLSPDiagramContextKeyService)
protected readonly contextKeyService: GLSPDiagramContextKeyService;

abstract get fileExtensions(): string[];

async doOpen(widget: DiagramWidget, options?: WidgetOpenerOptions) {
Expand Down
1 change: 1 addition & 0 deletions src/browser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export * from './diagram/glsp-theia-diagram-server';
export * from './diagram/glsp-theia-sprotty-connector';
export * from './diagram/glsp-notification-manager';
export * from './diagram/glsp-theia-context-menu-service';
export * from './diagram/glsp-diagram-context-key-service';

// language export
export * from './language/glsp-client';
Expand Down

0 comments on commit 0b7d765

Please sign in to comment.