Skip to content

Commit

Permalink
PR Feedback
Browse files Browse the repository at this point in the history
- Restore usage of accessibility module
- Bind grid using TYPES.Grid instead of using local symbol
- Fix using grid in movement key tool
- Re-work rendering of grid background directly in graph

- Bonus: Add OriginViewportAction to reset to 0,0 on zoom-level 1

Contributed on behalf of Axon Ivy AG
  • Loading branch information
martin-fleck-at committed May 14, 2024
1 parent 456821c commit 8486c8b
Show file tree
Hide file tree
Showing 29 changed files with 293 additions and 117 deletions.
6 changes: 3 additions & 3 deletions examples/workflow-glsp/src/workflow-startup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@

import { GridManager, IDiagramStartup } from '@eclipse-glsp/client';
import { MaybePromise, TYPES } from '@eclipse-glsp/sprotty';
import { inject, injectable } from 'inversify';
import { inject, injectable, optional } from 'inversify';

@injectable()
export class WorkflowStartup implements IDiagramStartup {
rank = -1;

@inject(TYPES.IGridManager) protected gridManager: GridManager;
@optional() @inject(TYPES.IGridManager) protected gridManager?: GridManager;

preRequestModel(): MaybePromise<void> {
this.gridManager.setGridVisible(true);
this.gridManager?.setGridVisible(true);
}
}
13 changes: 11 additions & 2 deletions examples/workflow-standalone/src/di.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import {
LogLevel,
STANDALONE_MODULE_CONFIG,
TYPES,
accessibilityModule,
bindOrRebind,
createDiagramOptionsModule
createDiagramOptionsModule,
toolPaletteModule
} from '@eclipse-glsp/client';
import { Container } from 'inversify';
import { makeLoggerMiddleware } from 'inversify-logger-middleware';
Expand All @@ -33,7 +35,14 @@ export default function createContainer(options: IDiagramOptions): Container {
if (parameters.readonly) {
options.editMode = EditMode.READONLY;
}
const container = createWorkflowDiagramContainer(createDiagramOptionsModule(options), STANDALONE_MODULE_CONFIG);
const container = createWorkflowDiagramContainer(
createDiagramOptionsModule(options),
{
add: accessibilityModule,
remove: toolPaletteModule
},
STANDALONE_MODULE_CONFIG
);
bindOrRebind(container, TYPES.ILogger).to(ConsoleLogger).inSingletonScope();
bindOrRebind(container, TYPES.LogLevel).toConstantValue(LogLevel.warn);
container.bind(TYPES.IMarqueeBehavior).toConstantValue({ entireEdge: true, entireElement: true });
Expand Down
2 changes: 1 addition & 1 deletion packages/client/css/debug.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2024 EclipseSource and others.
* Copyright (c) 2024 Axon Ivy AG and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down
3 changes: 2 additions & 1 deletion packages/client/css/grid.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2024 EclipseSource and others.
* Copyright (c) 2024 Axon Ivy AG and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -15,6 +15,7 @@
********************************************************************************/

:root {
/* default grid background image, is typically overridden in the graph view but might also be overwritten using CSS. */
--grid-background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10"><rect class="grid-background-grid" width="10" height="10" x="0" y="0" fill="none" stroke="black" stroke-width="1" stroke-opacity="0.10" /></svg>');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ export class KeyboardToolPalette extends ToolPalette {
this.headerToolsButtonMapping.set(mappingIndex++, this.validateToolButton);
headerTools.appendChild(this.validateToolButton);

const resetViewportButton = this.createResetViewportButton();
this.headerToolsButtonMapping.set(mappingIndex++, resetViewportButton);
headerTools.appendChild(resetViewportButton);

if (this.gridManager) {
const toggleGridButton = this.createToggleGridButton();
this.headerToolsButtonMapping.set(mappingIndex++, toggleGridButton);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ export class ResizeElementHandler implements IActionHandler {
// Default y resize used if grid is not provided
static readonly defaultResizeY = 20;

@optional() @inject(Grid) protected grid: Grid = { x: ResizeElementHandler.defaultResizeX, y: ResizeElementHandler.defaultResizeY };
@optional() @inject(TYPES.Grid) protected grid: Grid = {
x: ResizeElementHandler.defaultResizeX,
y: ResizeElementHandler.defaultResizeY
};

protected isEditMode = false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,22 @@ export class MovementKeyTool implements Tool {

isEditTool = true;

protected readonly movementKeyListener = new MoveKeyListener(this);
protected movementKeyListener: MoveKeyListener;

@inject(KeyTool) protected readonly keytool: KeyTool;
@inject(SelectionService) selectionService: SelectionService;
@inject(TYPES.ISnapper) @optional() readonly snapper?: ISnapper;
@inject(TYPES.IActionDispatcher) readonly actionDispatcher: GLSPActionDispatcher;
@optional() @inject(TYPES.Grid) protected grid: Grid;

get id(): string {
return MovementKeyTool.ID;
}

enable(): void {
if (!this.movementKeyListener) {
this.movementKeyListener = new MoveKeyListener(this, this.grid);
}
this.keytool.register(this.movementKeyListener);
this.movementKeyListener.registerShortcutKey();
}
Expand All @@ -64,9 +68,10 @@ export class MoveKeyListener extends KeyListener implements AccessibleKeyShortcu

protected readonly token = MoveKeyListener.name;

@optional() @inject(Grid) protected grid: Grid = { x: MoveKeyListener.defaultMoveX, y: MoveKeyListener.defaultMoveY };

constructor(protected readonly tool: MovementKeyTool) {
constructor(
protected readonly tool: MovementKeyTool,
protected grid: Grid = { x: MoveKeyListener.defaultMoveX, y: MoveKeyListener.defaultMoveY }
) {
super();
}

Expand Down
10 changes: 5 additions & 5 deletions packages/client/src/features/debug/debug-bounds-decorator.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2024 EclipseSource and others.
* Copyright (c) 2024 Axon Ivy AG and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -15,7 +15,7 @@
********************************************************************************/
/* eslint-disable max-len */

import { Bounds, GModelElement, IVNodePostprocessor, Point, isSizeable, setClass, svg } from '@eclipse-glsp/sprotty';
import { Bounds, GModelElement, IVNodePostprocessor, Point, isBoundsAware, setClass, svg } from '@eclipse-glsp/sprotty';
import { inject, injectable, optional } from 'inversify';
import { VNode } from 'snabbdom';
import { GGraph } from '../../model';
Expand All @@ -35,8 +35,8 @@ export class DebugBoundsDecorator implements IVNodePostprocessor {
if (!this.debugManager?.isDebugEnabled) {
return vnode;
}
if (isSizeable(element)) {
this.decorateSizeable(vnode, element);
if (isBoundsAware(element)) {
this.decorateBoundsAware(vnode, element);
}
if (element instanceof GGraph) {
this.decorateGraph(vnode, element);
Expand Down Expand Up @@ -69,7 +69,7 @@ export class DebugBoundsDecorator implements IVNodePostprocessor {
);
}

protected decorateSizeable(vnode: VNode, element: BoundsAwareModelElement): void {
protected decorateBoundsAware(vnode: VNode, element: BoundsAwareModelElement): void {
setClass(vnode, 'debug-bounds', true);
vnode.children?.push(this.renderTopLeftCorner(element));
vnode.children?.push(this.renderTopRightCorner(element));
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/features/debug/debug-manager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2024 EclipseSource and others.
* Copyright (c) 2024 Axon Ivy AG and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/features/debug/debug-model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2024 EclipseSource and others.
* Copyright (c) 2024 Axon Ivy AG and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/features/debug/debug-module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2024 EclipseSource and others.
* Copyright (c) 2024 Axon Ivy AG and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/features/debug/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2024 EclipseSource and others.
* Copyright (c) 2024 Axon Ivy AG and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down
72 changes: 0 additions & 72 deletions packages/client/src/features/grid/grid-background.ts

This file was deleted.

106 changes: 106 additions & 0 deletions packages/client/src/features/grid/grid-graph-view.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/********************************************************************************
* Copyright (c) 2024 Axon Ivy AG and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import {
Bounds,
Dimension,
GGraphView,
GViewportRootElement,
IViewArgs,
Point,
RenderingContext,
SGraphImpl,
TYPES,
Writable
} from '@eclipse-glsp/sprotty';
import { inject, injectable } from 'inversify';
import { VNode, VNodeStyle } from 'snabbdom';
import { GLSPProjectionView } from '../../views';
import { GridManager } from './grid-manager';

@injectable()
export class GridGraphView extends GGraphView {
@inject(TYPES.IGridManager) protected gridManager: GridManager;

override render(model: Readonly<SGraphImpl>, context: RenderingContext): VNode {
const graph = super.render(model, context);
if (graph.data) {
graph.data!.style = { ...graph.data.style, ...this.backgroundStyle(model) };
}
return graph;
}

protected backgroundStyle(model: Readonly<SGraphImpl>): VNodeStyle & Partial<CSSStyleDeclaration> {
if (!this.gridManager.isGridVisible) {
return {};
}
const bounds = this.getBackgroundBounds(model);
// we do not set the background image directly in the style object, because we want to toggle it on and off via CSS
return {
backgroundPosition: `${bounds.x}px ${bounds.y}px`,
backgroundSize: `${bounds.width}px ${bounds.height}px`,
'--grid-background-image': this.getBackgroundImage(model)
};
}

protected getBackgroundBounds(viewport: Readonly<SGraphImpl>): Writable<Bounds> {
const position = Point.multiplyScalar(Point.subtract(this.gridManager.grid, viewport.scroll), viewport.zoom);
const size = Dimension.fromPoint(Point.multiplyScalar(this.gridManager.grid, viewport.zoom));
return { ...position, ...size };
}

protected getBackgroundImage(model: Readonly<SGraphImpl>): string {
// eslint-disable-next-line max-len
return `url('data:image/svg+xml;utf8, <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${this.gridManager.grid.x} ${this.gridManager.grid.y}"><rect width="${this.gridManager.grid.x}" height="${this.gridManager.grid.y}" x="0" y="0" fill="none" stroke="black" stroke-width="1" stroke-opacity="0.10" /></svg>')`;
}
}

@injectable()
export class GridProjectionGraphView extends GLSPProjectionView {
@inject(TYPES.IGridManager) protected gridManager: GridManager;

protected override renderSvg(model: Readonly<GViewportRootElement>, context: RenderingContext, args?: IViewArgs | undefined): VNode {
const graph = super.renderSvg(model, context);
if (graph.data) {
graph.data!.style = { ...graph.data.style, ...this.backgroundStyle(model) };
}
return graph;
}

protected backgroundStyle(model: Readonly<SGraphImpl>): VNodeStyle & Partial<CSSStyleDeclaration> {
if (!this.gridManager.isGridVisible) {
return {};
}
const bounds = this.getBackgroundBounds(model);
// we do not set the background image directly in the style object, because we want to toggle it on and off via CSS
return {
backgroundPosition: `${bounds.x}px ${bounds.y}px`,
backgroundSize: `${bounds.width}px ${bounds.height}px`,
'--grid-background-image': this.getBackgroundImage(model)
};
}

protected getBackgroundBounds(viewport: Readonly<SGraphImpl>): Writable<Bounds> {
const position = Point.multiplyScalar(Point.subtract(this.gridManager.grid, viewport.scroll), viewport.zoom);
const size = Dimension.fromPoint(Point.multiplyScalar(this.gridManager.grid, viewport.zoom));
return { ...position, ...size };
}

protected getBackgroundImage(model: Readonly<SGraphImpl>): string {
// eslint-disable-next-line max-len
return `url('data:image/svg+xml;utf8, <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${this.gridManager.grid.x} ${this.gridManager.grid.y}"><rect width="${this.gridManager.grid.x}" height="${this.gridManager.grid.y}" x="0" y="0" fill="none" stroke="black" stroke-width="1" stroke-opacity="0.10" /></svg>')`;
}
}
4 changes: 2 additions & 2 deletions packages/client/src/features/grid/grid-manager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2024 EclipseSource and others.
* Copyright (c) 2024 Axon Ivy AG and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -28,7 +28,7 @@ export class GridManager implements IActionHandler {
@inject(TYPES.IFeedbackActionDispatcher)
protected feedbackDispatcher: IFeedbackActionDispatcher;

@inject(Grid)
@inject(TYPES.Grid)
public readonly grid: Grid;

get isGridVisible(): boolean {
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/features/grid/grid-model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2024 EclipseSource and others.
* Copyright (c) 2024 Axon Ivy AG and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down
Loading

0 comments on commit 8486c8b

Please sign in to comment.