Skip to content

Commit

Permalink
Fix rendering, freezes and vscode shortcuts (#105)
Browse files Browse the repository at this point in the history
* Fix blurry children caused by css filter

* Fix wrapping edge breaking points in free form layout

* Disable association navigable property

* Update demo example to use association

* Propagate set dirty action to webview in vscode

* Exclude layout and svg export commands

* Trigger extension shortcuts only if in correct context

* Use tree kill package for stopping server processes

* Show name in the center of association edge

* Add vscode extension readme
  • Loading branch information
haydar-metin authored Apr 14, 2023
1 parent ad3e40e commit 1420a38
Show file tree
Hide file tree
Showing 23 changed files with 267 additions and 60 deletions.
3 changes: 2 additions & 1 deletion client/packages/uml-glsp/css/base/node.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.uml-node {
fill: var(--uml-node);
filter: var(--svg-def-filter-drop-shadow);
/*TODO: Causes blur effects in children*/
/*filter: var(--svg-def-filter-drop-shadow);*/
stroke-width: 1;
stroke: var(--uml-border);
}
Expand Down
4 changes: 4 additions & 0 deletions client/packages/uml-glsp/src/di.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import '../css/style.css';

import {
configureDefaultModelElements,
configureLayout,
configureModelElement,
configureViewerOptions,
createDiagramContainer,
Expand All @@ -42,6 +43,7 @@ import propertyPaletteModule from './features/property-palette/di.config';
import { themeModule } from './features/theme/di.config';
import { FixedFeedbackActionDispatcher } from './features/tool-feedback/feedback-action-dispatcher';
import umlToolPaletteModule from './features/tool-palette/di.config';
import { UmlFreeFormLayouter } from './graph/layout/uml-freeform.layout';
import { SVGIdCreatorService } from './graph/svg-id-creator.service';
import { UmlGraphProjectionView } from './graph/uml-graph-projection.view';
import { umlDiagramModules } from './uml/index';
Expand All @@ -65,6 +67,8 @@ export default function createContainer(widgetId: string): Container {
bind(TYPES.IVNodePostprocessor).to(IconLabelCompartmentSelectionFeedback);
bind(SVGIdCreatorService).toSelf().inSingletonScope();

configureLayout({ bind, isBound }, UmlFreeFormLayouter.KIND, UmlFreeFormLayouter);

configureDefaultModelElements(context);

configureModelElement(context, DefaultTypes.GRAPH, GLSPGraph, UmlGraphProjectionView);
Expand Down
50 changes: 50 additions & 0 deletions client/packages/uml-glsp/src/graph/layout/uml-freeform.layout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/********************************************************************************
* Copyright (c) 2023 EclipseSource 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 { isSizeable, LayoutContainer, SParentElement, StatefulLayouter } from '@eclipse-glsp/client';
import { FreeFormLayouter } from '@eclipse-glsp/client/lib/features/layout/freeform-layout';
import { Dimension } from '@eclipse-glsp/protocol';
import { injectable } from 'inversify';
import { AbstractLayoutOptions } from 'sprotty/lib/features/bounds/layout-options';

@injectable()
export class UmlFreeFormLayouter extends FreeFormLayouter {
static override KIND = 'uml-freeform';

protected override getChildrenSize(
container: SParentElement & LayoutContainer,
containerOptions: AbstractLayoutOptions,
layouter: StatefulLayouter
): Dimension {
let maxX = 0;
let maxY = 0;
container.children
.filter(child => isSizeable(child))
.forEach(child => {
const bounds = layouter.getBoundsData(child).bounds;
if (bounds !== undefined && Dimension.isValid(bounds)) {
const childMaxX = bounds.x + bounds.width;
const childMaxY = bounds.y + bounds.height;
maxX = Math.max(maxX, childMaxX);
maxY = Math.max(maxY, childMaxY);
}
});
return {
width: maxX,
height: maxY
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.vsix
50 changes: 50 additions & 0 deletions client/packages/uml-vscode-integration/extension/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# bigUML - VS Code Extension

<!-- DESCRIPTION -->

> [Open-source](https://github.com/borkdominik/bigUML) **UML Modeling Tool** for [Visual Studio Code](https://code.visualstudio.com/) supporting graphical editing diagrams.
<p align="center">
<img src="./resources/biguml-vscode.png" alt="Demo" width="800" />
</p>

<br />

**📖 Table of Contents**

1. [Diagrams](#diagrams)
2. [Requirements](#requirements)
3. [Examples](#examples)
- [Create new model](#create-new-model)

<br />

## Diagrams

The supported diagrams are visible in the table. More diagrams will be supported in the future.

### Structure Diagrams

| SD | Class | Component | Deployment | Object | Package | Profile | Composite |
| ------ | ----------- | --------- | ---------- | ------ | ------- | ------- | --------- |
| Status | In progress | - | - | - | - | - | - |

### Behavior Diagrams

| BD | Use Case | Activity | State Machine | Sequence | Communication | Interaction | Timing |
| ------ | -------- | -------- | ------------- | ------------------------ | ------------------- | ----------- | ------ |
| Status | - | - | - | Contribution in progress | Development started | - | - |

## Requirements

This extension requires Java JRE 11+ to run.

_In the background two Java-based language servers will be started._

## Examples

### Create new model

You can create a new model by either using the command `bigUML: New Empty UML Diagram` or with `File -> New File`.

![New File Command](./resources/new-model-command.png)
67 changes: 27 additions & 40 deletions client/packages/uml-vscode-integration/extension/package.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
{
"name": "biguml-vscode",
"name": "umldiagram",
"displayName": "bigUML Modeling Tool",
"version": "0.1.0",
"description": "UML-VSCode extension",
"description": "Graphical UML Editor",
"categories": [
"Programming Languages"
"Programming Languages",
"Visualization",
"Education"
],
"keywords": [
"UML",
"Unified Modeling Language",
"UML Diagram",
"Modeling Tool"
],
"homepage": "https://github.com/borkdominik/bigUML",
"bugs": "https://github.com/borkdominik/bigUML/issues",
"repository": {
"type": "git",
"url": "https://github.com/borkdominik/bigUML.git"
"url": "https://github.com/borkdominik/bigUML"
},
"publisher": "BIGModelingTools",
"main": "./lib/main",
Expand All @@ -22,13 +30,14 @@
],
"scripts": {
"build": "tsx .esbuild.mts",
"build:prod": "yarn build --es-minify",
"build:prod": "yarn clean && yarn build --es-minify",
"clean": "rimraf lib tsconfig.tsbuildinfo server/**/*.log",
"lint": "eslint --ext .ts,.tsx ./src",
"lint:ci": "yarn lint -o eslint.xml -f checkstyle",
"lint:fix": "eslint --fix --ext .ts,.tsx ./src",
"package": "vsce package --yarn",
"prepare": "yarn clean && yarn build",
"vscode:package": "vsce package --yarn",
"vscode:package-pre": "yarn vscode:package --pre-release",
"vscode:prepublish": "yarn build:prod",
"watch": "yarn build --es-watch"
},
Expand All @@ -51,18 +60,6 @@
"title": "Center selection",
"category": "bigUML",
"enablement": "activeCustomEditorId == 'bigUML.diagramView'"
},
{
"command": "bigUML.layout",
"title": "Layout diagram",
"category": "bigUML",
"enablement": "activeCustomEditorId == 'bigUML.diagramView'"
},
{
"command": "bigUML.exportAsSVG",
"title": "Export as SVG",
"category": "bigUML",
"enablement": "activeCustomEditorId == 'bigUML.diagramView'"
}
],
"configuration": {
Expand Down Expand Up @@ -92,25 +89,19 @@
"key": "alt+f",
"mac": "alt+f",
"command": "bigUML.fit",
"when": "activeCustomEditorId == 'bigUML.diagramView'"
"when": "focusedView == '' && !inputFocus && activeCustomEditorId == 'bigUML.diagramView'"
},
{
"key": "alt+c",
"mac": "alt+c",
"command": "bigUML.center",
"when": "activeCustomEditorId == 'bigUML.diagramView'"
"when": "focusedView == '' && !inputFocus && activeCustomEditorId == 'bigUML.diagramView'"
},
{
"key": "ctrl+a",
"mac": "ctrl+a",
"command": "bigUML.selectAll",
"when": "activeCustomEditorId == 'bigUML.diagramView'"
},
{
"key": "alt+l",
"mac": "alt+l",
"command": "bigUML.layout",
"when": "activeCustomEditorId == 'bigUML.diagramView'"
"when": "focusedView == '' && !inputFocus && activeCustomEditorId == 'bigUML.diagramView'"
}
],
"languages": [
Expand Down Expand Up @@ -168,15 +159,6 @@
"command": "bigUML.center",
"group": "navigation",
"when": "activeCustomEditorId == 'bigUML.diagramView'"
},
{
"command": "bigUML.layout",
"group": "navigation",
"when": "activeCustomEditorId == 'bigUML.diagramView'"
},
{
"command": "bigUML.exportAsSVG",
"when": "activeCustomEditorId == 'bigUML.diagramView'"
}
]
},
Expand All @@ -190,8 +172,7 @@
"activationEvents": [
"onLanguage:bigUML.uml",
"onLanguage:bigUML.unotation",
"onCommand:bigUML.model.newEmpty",
"workspaceContains:**/*.uml"
"onCommand:bigUML.model.newEmpty"
],
"dependencies": {
"@borkdominik-biguml/uml-common": "*",
Expand All @@ -201,16 +182,22 @@
"@vscode/codicons": "^0.0.25",
"inversify": "5.1.1",
"reflect-metadata": "^0.1.13",
"tree-kill": "^1.2.2",
"urijs": "^1.19.11"
},
"devDependencies": {
"@borkdominik-biguml/uml-vscode-integration-webview": "*",
"@types/urijs": "1.19.11",
"@types/vscode": "^1.54.0",
"@types/vscode": "^1.63.0",
"@vscode/vsce": "^2.15.0",
"esbuild": "^0.17.10"
},
"engines": {
"vscode": "^1.54.0"
"vscode": "^1.63.0"
},
"icon": "./resources/logo.png",
"galleryBanner": {
"color": "#1d1d1d",
"theme": "dark"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@
import '../css/colors.css';

import { ModelServerConfig } from '@borkdominik-biguml/uml-modelserver/lib/config';
import { GlspVscodeConnector } from '@eclipse-glsp/vscode-integration';
import { configureDefaultCommands } from '@eclipse-glsp/vscode-integration/lib/quickstart-components';
import * as vscode from 'vscode';
import { createContainer } from './di.config';
import { TYPES, VSCODE_TYPES } from './di.types';
import { UVGlspConnector } from './glsp/connection/uv-glsp-connector';
import { UVGlspServer } from './glsp/connection/uv-glsp-server';
import { GlspServerConfig, launchGLSPServer } from './glsp/launcher/glsp-server-launcher';
import { VSCodeSettings } from './language';
import { launchModelServer } from './modelserver/launcher/modelserver-launcher';
import { freePort } from './utils/server';
import { configureDefaultCommands } from './vscode/command/default-commands';

const modelServerRoute = '/api/v2/';

Expand Down Expand Up @@ -56,7 +56,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>

configureDefaultCommands({
extensionContext: context,
connector: container.get<GlspVscodeConnector>(TYPES.Connector),
connector: container.get<UVGlspConnector>(TYPES.Connector),
diagramPrefix: VSCodeSettings.commands.prefix
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ export class UVGlspConnector<TDocument extends vscode.CustomDocument = vscode.Cu
}
}

return { processedMessage: message, messageChanged: false };
// TODO: Check why
// The webview client cannot handle `SetDirtyStateAction`s. Avoid propagation
return { processedMessage: GlspVscodeConnector.NO_PROPAGATION_MESSAGE, messageChanged: true };
// return { processedMessage: GlspVscodeConnector.NO_PROPAGATION_MESSAGE, messageChanged: true };
}

protected onClientMessage(client: GlspVscodeClient<TDocument>, message: unknown): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import * as fs from 'fs';
import { Container, inject, injectable } from 'inversify';
import * as net from 'net';
import * as path from 'path';
import kill from 'tree-kill';
import { TYPES, VSCODE_TYPES } from '../../di.types';
import { OutputChannel } from '../../vscode/output/output.channel';

Expand Down Expand Up @@ -143,9 +144,9 @@ export class UmlGLSPServerLauncher extends GlspServerLauncher {

override stop(): void {
if (this.serverProcess && this.serverProcess.pid && !this.serverProcess.killed) {
if (process.platform === 'win32') {
childProcess.execSync(`taskkill /F /T /PID ${this.serverProcess.pid}`);
} else {
kill(this.serverProcess.pid, 'SIGINT', error => console.error('Error', error));

if (!this.serverProcess.killed) {
this.serverProcess.kill('SIGINT');
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import * as fs from 'fs';
import { Container, inject, injectable } from 'inversify';
import * as net from 'net';
import * as path from 'path';
import kill from 'tree-kill';
import * as vscode from 'vscode';
import { TYPES, VSCODE_TYPES } from '../../di.types';
import { OutputChannel } from '../../vscode/output/output.channel';
Expand Down Expand Up @@ -163,9 +164,9 @@ export class ModelServerLauncher implements vscode.Disposable {
*/
stop(): void {
if (this.serverProcess && this.serverProcess.pid && !this.serverProcess.killed) {
if (process.platform === 'win32') {
childProcess.execSync(`taskkill /F /T /PID ${this.serverProcess.pid}`);
} else {
kill(this.serverProcess.pid, 'SIGINT', error => console.error('Error', error));

if (!this.serverProcess.killed) {
this.serverProcess.kill('SIGINT');
}
}
Expand Down
Loading

0 comments on commit 1420a38

Please sign in to comment.