Skip to content
Snippets Groups Projects
Commit 58d4ea38 authored by Smit, P.J.M. (Peter, Student M-CS)'s avatar Smit, P.J.M. (Peter, Student M-CS)
Browse files

added comments to the dotviewer files

parent a2894873
No related branches found
No related tags found
No related merge requests found
......@@ -14,10 +14,12 @@ var newPoint;
var scale;
var optionsOpen = false;
window.addEventListener('message', event => {
const type = event.data.type;
switch (type) {
case 'reset':
// reset the svg's position
if (svgImage !== undefined) {
scale = 1;
viewBox = { x: 0, y: 0, w: svgImage.clientWidth, h: svgImage.clientHeight };
......@@ -31,6 +33,7 @@ window.addEventListener('message', event => {
zoom(false);
break;
case 'svg':
// Handle a newly received svg
const newSvg = event.data.svg;
if (svgImage === undefined) {
svgContainer.innerHTML = newSvg.replace('<svg', '<svg id="svgImage"');
......@@ -44,12 +47,14 @@ window.addEventListener('message', event => {
}
break;
case 'params':
// Handle received parameters
if (paramList.innerHTML === '') {
event.data.params.forEach(addParameterItem);
parameterDefinitions = event.data.params;
}
break;
case 'paramValues':
// Handle received parameter values
resetParams();
// Set all the new values
const values = event.data.values;
......@@ -65,6 +70,8 @@ window.addEventListener('message', event => {
}
break;
case 'optionsOpen':
// Toggle the open options
optionsOpen = event.data.optionsOpen;
if (event.data.optionsOpen) {
paramContainer.style.maxHeight = '450px';
} else {
......@@ -75,7 +82,9 @@ window.addEventListener('message', event => {
});
/**
* resets all parameters in the dot options to their defaults
*/
function resetParams() {
if (parameterDefinitions) {
parameterDefinitions.forEach(param => {
......@@ -91,6 +100,7 @@ function resetParams() {
valueElem.value = param.defaultValue;
break;
default:
// Shouldn't happen
console.log("OKAY I DON'T KNOW THIS TYPE??? " + param.type.valueType);
break;
}
......@@ -98,7 +108,10 @@ function resetParams() {
}
}
/**
* adds a parameter to the dotOptions window
* @param {*} param the parameter to be added
*/
function addParameterItem(param) {
const li = document.createElement("li");
......@@ -171,6 +184,7 @@ function addParameterItem(param) {
});
break;
default:
// Shouldn't happen
console.log("OKAY I DON'T KNOW THIS TYPE??? " + param.type.valueType);
break;
};
......@@ -181,6 +195,8 @@ function addParameterItem(param) {
}
// -------------------------- Onclick handlers --------------------------
document.getElementById("openOptions").onclick = () => {
paramContainer.style.maxHeight = `${Math.min(window.innerHeight - 20, 450)}px`;
paramList.style.maxHeight = `${Math.min(window.innerHeight - 60, 410)}px`;
......@@ -190,7 +206,6 @@ document.getElementById("openOptions").onclick = () => {
});
};
document.getElementById("closeOptions").onclick = () => {
paramContainer.style.maxHeight = '0px';
optionsOpen = !optionsOpen;
......@@ -210,7 +225,7 @@ document.getElementById("revert").onclick = () => {
// Below is code to handle the calculation of the position of the svg. I have no idea how it works exactly.
// FULL CREDIT TO https://stackoverflow.com/questions/52576376/how-to-zoom-in-on-a-complex-svg-structure
// also https://stackoverflow.com/questions/1685326/responding-to-the-onmousemove-event-outside-of-the-browser-window-in-ie
window.addEventListener('resize', () => {
......
......@@ -77,7 +77,6 @@ export namespace DotViewer {
private fileUri: vscode.Uri;
private panel: vscode.WebviewPanel;
private webview: vscode.Webview;
private lastDotString: string | undefined;
private lastSvgString: string | undefined;
private dotParameters: Map<string, string> = new Map();
......@@ -85,28 +84,31 @@ export namespace DotViewer {
private lastRunToken: string | undefined;
private optionsOpen: boolean = false;
/**
* Creates and opens a new dot view.
* @param fileUri The Uri of the file the dot view is for
* @param sameColumn true if the view should be opened in the same column as the current window
*/
public constructor(fileUri: vscode.Uri, sameColumn = false) {
this.fileUri = fileUri;
this.panel = vscode.window.createWebviewPanel(
// Webview id
`liveDotView ${this.fileUri.path}`,
`liveDotView ${fileUri.path}`,
// Webview title
`[Preview] ${this.fileUri.path.split("/").pop()}`,
`[Preview] ${fileUri.path.split("/").pop()}`,
// This will open the second column for preview inside editor
sameColumn ? -1 : -2,
{
// Enable scripts in the webview
enableScripts: true,
// And restrict the webview to only loading content from our extension's `assets` directory.
// And restrict the webview to only loading content from our extension's base directory.
localResourceRoots: [extensionUri]
}
);
this.panel.webview.html = this.getHtml();
this.webview = this.panel.webview;
this.webview.html = this.getHtml();
// handle the disposal of the view
this.panel.onDidDispose(() => {
vscode.commands.executeCommand('setContext', 'modest:dotViewFocused', false);
LiveDotView.liveDotViews.delete(this.fileUri);
......@@ -115,30 +117,36 @@ export namespace DotViewer {
}
});
// If the viewState is changed (happens when you switch windows) send the info to the webview again,
// since the webview's information could be deleted
this.panel.onDidChangeViewState(
e => {
vscode.commands.executeCommand('setContext', 'modest:dotViewFocused', e.webviewPanel.active);
if (e.webviewPanel.active) {
LiveDotView.currentDotView = this;
}
// send the svg (if it exists)
if (this.lastSvgString) {
this.postMessage({
type: 'svg',
svg: this.lastSvgString,
});
}
// send the parameters (if they exist)
if (LiveDotView.availableParameters) {
this.postMessage({
type: 'params',
params: LiveDotView.availableParameters,
});
}
// send the parameters' values (if they exist)
if (this.dotParameters) {
this.postMessage({
type: 'paramValues',
values: Array.from(this.dotParameters.entries()),
});
}
// send if the options window should be open
this.postMessage({
type: 'optionsOpen',
optionsOpen: this.optionsOpen,
......@@ -146,18 +154,22 @@ export namespace DotViewer {
},
);
this.webview.onDidReceiveMessage(
//Handle received messages from the webview
this.panel.webview.onDidReceiveMessage(
message => {
switch (message.type) {
case 'paramUpdate':
// Update a parameter and update the dot
this.dotParameters.set(message.id, message.value);
this.updateDot();
break;
case 'paramReset':
// Reset the parameters and update the dot
this.dotParameters = new Map();
this.updateDot();
break;
case 'toggleOptions':
// Toggle the options
this.optionsOpen = !this.optionsOpen;
break;
}
......@@ -165,16 +177,22 @@ export namespace DotViewer {
);
// update the dot if the focument was saved
vscode.workspace.onDidSaveTextDocument(td => {
if (td.uri === this.fileUri) {
this.updateDot();
}
});
// Generate the dot for the first time
this.updateDot();
vscode.commands.executeCommand('setContext', 'modest:dotViewFocused', this.panel.active);
LiveDotView.currentDotView = this;
LiveDotView.liveDotViews.set(fileUri, this);
// Get the parameters if they're not available yet and send them to the webview.
if (!LiveDotView.availableParameters) {
client?.sendRequest<ParameterDefinitions>("modest/getParameters", { "toolName": "mosta (export-to-dot)" }).then(data => {
LiveDotView.availableParameters = data.parameterDefinitions.filter(param => !LiveDotView.filteredParameters.includes(param.id));
......@@ -191,7 +209,11 @@ export namespace DotViewer {
}
}
/**
* Create a new dotview or focus the dotivew with the given fileUri if it exists
* @param uri the uri of the file the dotview is for
* @param sameColumn true if the view should be opened in the same column as the current window
*/
public static addOrOpen(uri: vscode.Uri, sameColumn = false) {
if (!clientReady) {
vscode.window.showErrorMessage("Server not ready yet, try again later");
......@@ -205,10 +227,17 @@ export namespace DotViewer {
}
}
/**
* Post a message to this dotView's webview
* @param obj message to be posted
*/
public postMessage(obj: any) {
this.webview.postMessage(obj);
this.panel.webview.postMessage(obj);
}
/**
* Save this dotView's svg
*/
public saveSvg() {
if (this.lastSvgString) {
const defaultUri = vscode.workspace.workspaceFolders
......@@ -224,6 +253,9 @@ export namespace DotViewer {
}
}
/**
* Copy this dotView's svg
*/
public copySvg() {
if (this.lastSvgString) {
vscode.env.clipboard.writeText(this.lastSvgString);
......@@ -232,6 +264,9 @@ export namespace DotViewer {
}
}
/**
* Save this dotView's dot
*/
public saveDot() {
if (this.lastDotString) {
const defaultUri = vscode.workspace.workspaceFolders
......@@ -247,6 +282,9 @@ export namespace DotViewer {
}
}
/**
* Copy this dotView's dot
*/
public copyDot() {
if (this.lastDotString) {
vscode.env.clipboard.writeText(this.lastDotString);
......@@ -255,10 +293,15 @@ export namespace DotViewer {
}
}
/**
* Use the languageServer's modest/runTool method to convert the current file into a dot and update the webview accordingly
*/
private updateDot() {
let uri = this.fileUri.toString();
let parameters = [];
// Collect all changed parameters
let parameters = [];
for (const entry of this.dotParameters.entries()) {
parameters.push({
id: entry[0],
......@@ -276,26 +319,33 @@ export namespace DotViewer {
parameters: parameters,
runToken: "dot" + runToken
};
//Create a progress indicator that goed away when resolveProgress is called
vscode.window.withProgress({ location: vscode.ProgressLocation.Window, title: `Loading new dot for ${this.fileUri.path.split("/").pop()}` }, async (progress, token) => {
await new Promise<null>(async (resolveProgress, _) => {
try {
let resultHandler = (data: ResultNotification) => {
if (data.runToken === jsonObject.runToken) {
if (data.data && data.data !== "") {
// Looks like that went successfully, we received a dot
try {
// Since this worked, let's save these parameters and the dot
this.lastWorkingParameters = dotParametersCopy;
this.lastDotString = data.data;
// Generate and display an svg from this dot
this.dotToSvg(runToken, resolveProgress);
} catch (error) {
console.error(error);
}
} else {
// Hmmmm, apparently this combination of parameters gave an error
// Reset the parameters to the last known working parameterset
this.dotParameters = new Map(this.lastWorkingParameters);
this.postMessage({
type: 'paramValues',
values: Array.from(this.dotParameters.entries())
});
}
// Remove this resulthandler from the list
resultHandlers.splice(resultHandlers.indexOf(resultHandler), 1);
resolveProgress(null);
}
......@@ -317,20 +367,28 @@ export namespace DotViewer {
});
}
/**
* Convert this object's lastDotString to an svg using the language server's modest/dot method
* @param runToken the runtoken to be used
* @param resolveProgress a function which resolves the progress indicator when it's called
*/
private dotToSvg(runToken: string, resolveProgress: (value: any | PromiseLike<any>) => void) {
let jsonObject = {
dot: this.lastDotString,
runToken: "svg" + runToken
};
// Cancel the last run if it exists
if (this.lastRunToken) {
client?.sendRequest("modest/cancelRun", { runToken: this.lastRunToken });
}
// Set the last run to this
this.lastRunToken = runToken;
let resultHandler = (data: ResultNotification) => {
if (data.runToken === jsonObject.runToken) {
if (data.data && data.data !== "") {
// The svg is received, set it in lastSvgString and pass it on to the webview
try {
this.lastSvgString = data.data;
this.postMessage({
......@@ -342,6 +400,7 @@ export namespace DotViewer {
console.error(error);
}
}
// Remove this resulthandler from the list
resultHandlers.splice(resultHandlers.indexOf(resultHandler), 1);
resolveProgress(null);
......@@ -359,8 +418,12 @@ export namespace DotViewer {
/**
* Generate the html for this dotView's webview
* @returns the html for the webview
*/
private getHtml() {
let webview = this.webview;
let webview = this.panel.webview;
const scriptUri = webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, "media", "dotview.js"));
const styleResetUri = webview.asWebviewUri(vscode.Uri.joinPath(extensionUri, 'media', 'reset.css'));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment