diff --git a/WebSocketClient/index.html b/WebSocketClient/index.html index 6b86e1d..1008a44 100644 --- a/WebSocketClient/index.html +++ b/WebSocketClient/index.html @@ -1,105 +1,110 @@ - - - - - - - UVL Playground - - -
-

UVL Playground

-

-
-
- -
- -
-

Get the UVLS VSCode Extension

-

You are trying to access the Configuration Page for Feature Models. - As by now, the Web-Playground does not support this, but it is available in the VSCode Extension! - Here is a preview: -

- Preview -

Get the extension here

-
-
-
-
-
+ + + + + + + + + UVL Playground + + +
+

UVL Playground

+

+
+ +
+ +
+
-
+

Get the UVLS VSCode Extension

+

You are trying to access the Configuration Page for Feature Models. + As by now, the Web-Playground does not support this, but it is available in the VSCode Extension! + Here is a preview: +

+ Preview +

Get the extension here +

+
+
+
+
+
+
+
-
-
- +
+
-
-
- - - + - + dragElement(document.getElementById("separator"), "H"); + + diff --git a/WebSocketClient/package-lock.json b/WebSocketClient/package-lock.json index 41ef745..42def1f 100644 --- a/WebSocketClient/package-lock.json +++ b/WebSocketClient/package-lock.json @@ -19,6 +19,7 @@ "@codingame/monaco-vscode-theme-service-override": "~1.83.2", "@viz-js/viz": "^3.2.3", "dotenv": "^16.3.1", + "intro.js": "^7.2.0", "lodash": "^4.17.21", "monaco-editor": "^0.44.0", "monaco-editor-workers": "~0.44.0", @@ -594,6 +595,11 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/intro.js": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/intro.js/-/intro.js-7.2.0.tgz", + "integrity": "sha512-qbMfaB70rOXVBceIWNYnYTpVTiZsvQh/MIkfdQbpA9di9VBfj1GigUPfcCv3aOfsbrtPcri8vTLTA4FcEDcHSQ==" + }, "node_modules/jsonc-parser": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", diff --git a/WebSocketClient/package.json b/WebSocketClient/package.json index 9115e1c..2db61fd 100644 --- a/WebSocketClient/package.json +++ b/WebSocketClient/package.json @@ -28,6 +28,7 @@ "@codingame/monaco-vscode-theme-service-override": "~1.83.2", "@viz-js/viz": "^3.2.3", "dotenv": "^16.3.1", + "intro.js": "^7.2.0", "lodash": "^4.17.21", "monaco-editor": "^0.44.0", "monaco-editor-workers": "~0.44.0", diff --git a/WebSocketClient/src/intro.ts b/WebSocketClient/src/intro.ts new file mode 100644 index 0000000..4a86c97 --- /dev/null +++ b/WebSocketClient/src/intro.ts @@ -0,0 +1,36 @@ +import introJs from "intro.js"; +import { sendGenerateGraphCommand } from "./main"; + + +export const initIntroJS = () => { + + + var intro = introJs(); + + intro.setOptions({ + steps: [{ + element: '#container', intro: 'This is the texteditor where you write and edit your uvl feature model.', + }, { + element: '.codelens-decoration', intro: 'You can use the buttons to activate and deactivate functionality.' + }, { + element: "[id='1']", + intro: 'Click here to visualize your feature model und click on it again to hide it again.' + }, { + element: "#separator", intro: 'You can change the size of the editor and the visualization with your mouse.' + }], + }); + + const button = document.getElementById("tutorialButton"); + + intro.onchange(function(targetElement) { + if(targetElement.id === "1"){ + sendGenerateGraphCommand(); + } + + }); + + button?.addEventListener("click", () => { + intro.start(); + }); + +} \ No newline at end of file diff --git a/WebSocketClient/src/main.ts b/WebSocketClient/src/main.ts index 188272e..0d536fc 100644 --- a/WebSocketClient/src/main.ts +++ b/WebSocketClient/src/main.ts @@ -26,6 +26,7 @@ import lodash from 'lodash'; import { ExecuteCommandRequest } from 'vscode-languageserver-protocol' import { buildWorkerDefinition } from 'monaco-editor-workers'; +import {initIntroJS} from "./intro.ts"; buildWorkerDefinition('./node_modules/monaco-editor-workers/dist/workers', new URL('', window.location.href).href, false); const languageId = 'uvls'; @@ -34,6 +35,7 @@ let fileID; let model; const connectionText = document.getElementById("connection"); let debounceGenGraph; +let updateGraph = false; const MAX_NUMBER_LINES = 100; const createUrl = (hostname: string, port: number, path: string, searchParams: Record = {}, secure: boolean): string => { @@ -123,6 +125,14 @@ const createLanguageClient = (transports: MessageTransports): MonacoLanguageClie middleware: { executeCommand(command, args, next) { const information = {command: command, arguments: args}; + debounceGenGraph = lodash.debounce(() => { + client?.sendRequest(ExecuteCommandRequest.type, information).then((res) => { + createDiagramFromDot(res as string); + }); + }, 500); + console.log("command: " + command); + console.log("args: " + args); + if(command === "uvls/open_config") { const dialog: HTMLDialogElement | null = document.querySelector("#dialog") const modalClose: HTMLButtonElement | null = document.querySelector('#modalClose'); @@ -138,12 +148,8 @@ const createLanguageClient = (transports: MessageTransports): MonacoLanguageClie createDiagramFromDot(res as string); }); - if(debounceGenGraph === undefined){ - debounceGenGraph = lodash.debounce(() => { - client?.sendRequest(ExecuteCommandRequest.type, information).then((res) => { - createDiagramFromDot(res as string); - }); - }, 500); + if(!updateGraph){ + updateGraph = true; const firstPane = document.getElementById("first"); const secondPane = document.getElementById("second"); @@ -153,7 +159,7 @@ const createLanguageClient = (transports: MessageTransports): MonacoLanguageClie } }else{ - debounceGenGraph = undefined; + updateGraph = false; const div = document.getElementsByClassName("graph"); const firstPane = document.getElementById("first"); while (div[0].firstChild) { @@ -277,11 +283,12 @@ export const startPythonClient = async () => { } } debouncedSave(); - if(debounceGenGraph !== undefined){ + if(updateGraph && debounceGenGraph !== undefined){ debounceGenGraph(); } }) + initIntroJS(); const debouncedSave = lodash.debounce(saveFm, 1000); }; @@ -299,4 +306,8 @@ function saveFm(){ const content = model.textEditorModel?.getValue(); window.localStorage.setItem("fm", content); } +} + +export function sendGenerateGraphCommand(){ + vscode.commands.executeCommand("uvls/generate_diagram", `file:///workspace/${fileID}.uvl`); } \ No newline at end of file diff --git a/WebSocketClient/style.css b/WebSocketClient/style.css index 3afaa35..e1ce0c2 100644 --- a/WebSocketClient/style.css +++ b/WebSocketClient/style.css @@ -1,103 +1,132 @@ /* Reset default browser styles */ body, h1, p { - margin: 0; - padding: 0; + margin: 0; + padding: 0; } body { - font-family: Arial, sans-serif; - background-color: #1e1e1e; /* Dark background color */ - color: #ffffff; /* Light text color */ + font-family: Arial, sans-serif; + background-color: #1e1e1e; /* Dark background color */ } .container { - display: flex; - width: 50%; - height: 100% + display: flex; + width: 50%; + height: 100% } .header { - text-align: center; + text-align: center; + color: #ffffff; /* Light text color */ } .footer { - text-align: center; + text-align: center; + color: #ffffff; /* Light text color */ } .graph { - overflow: scroll; - background: #1e1e1e; - height: 100%; + overflow: scroll; + background: #1e1e1e; + height: 100%; } #SVGGraph { - margin: 30vh auto; - display: block; + margin: 30vh auto; + display: block; +} + +.tooltip * { + background-color: #1e1e1e; + color: white; + + & button { + border: 2px solid red; + } +} + +.tooltip { + & button { + border: 2px solid red; + } } ::backdrop { - background-image: linear-gradient( - 45deg, - darkgray, - black - ); - opacity: 0.75; + background-image: linear-gradient( + 45deg, + darkgray, + black + ); + opacity: 0.75; } #dialog { - background: #1e1e1e; - color: white; - width: 50vw; - height: 70vh; - - #gif_in_dialog { - display: block; - margin: 10px auto; - max-width: 40vw; - min-width: 20vw; - } + background: #1e1e1e; + color: white; + width: 50vw; + height: 70vh; + + #gif_in_dialog { + display: block; + margin: 10px auto; + max-width: 40vw; + min-width: 20vw; + } - & div { - text-align: right; + & div { + text-align: right; - & button { - color: white; - background: #1e1e1e; - border: none; - font-size: 20pt; + & button { + color: white; + background: #1e1e1e; + border: none; + font-size: 20pt; + } } - } } h1 { - font-size: 30px; - margin-bottom: 20px; - text-align: center; + font-size: 30px; + margin-bottom: 20px; + text-align: center; } .editor { - background-color: #2d2d2d; - border-radius: 5px; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); - min-width: 50%; - max-width: 100%; - height:80vh; - border:1px solid grey; + background-color: #2d2d2d; + border-radius: 5px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + min-width: 50%; + max-width: 100%; + height: 80vh; + border: 1px solid grey; } p { - font-size: 20px; - line-height: 1.5; - margin-top: 20px; - width: 80%; - hyphens: auto; - text-align: justify; - margin-left: auto; - margin-right: auto; -} - -a:link { color: lightskyblue; } -a:visited { color: rgb(73, 185, 255); } -a:hover { color: #ffffff; } -a:active { color: #ff4040; text-decoration:none; font-weight:normal; } \ No newline at end of file + font-size: 20px; + line-height: 1.5; + margin-top: 20px; + width: 80%; + hyphens: auto; + text-align: justify; + margin-left: auto; + margin-right: auto; +} + +a:link { + color: lightskyblue; +} + +a:visited { + color: rgb(73, 185, 255); +} + +a:hover { + color: #ffffff; +} + +a:active { + color: #ff4040; + text-decoration: none; + font-weight: normal; +} \ No newline at end of file diff --git a/WebSocketLanguageServer/package-lock.json b/WebSocketLanguageServer/package-lock.json index 4b0cb4c..01101b1 100644 --- a/WebSocketLanguageServer/package-lock.json +++ b/WebSocketLanguageServer/package-lock.json @@ -11,7 +11,6 @@ "dependencies": { "@types/express": "^4.17.20", "@types/ws": "^8.5.7", - "bidirectional-map": "^1.1.1", "express": "^4.18.2", "vscode-languageserver": "^9.0.1", "vscode-ws-jsonrpc": "^3.0.0", @@ -159,11 +158,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/bidirectional-map": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/bidirectional-map/-/bidirectional-map-1.1.1.tgz", - "integrity": "sha512-qfpqHKQbSpc5Eev0W35FZoPnoNUvItDrHbVU0YYKkAOBCZ4Dp3CYi9tjAQcdmqN6ui/9+ioIkb9m0uz8EZqPkA==" - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",