const vscode = acquireVsCodeApi(); const svgContainer = document.getElementById("svgContainer"); const paramContainer = document.getElementById("paramContainer"); const paramList = document.getElementById("paramList"); var svgImage; var parameterDefinitions; var viewBox; var lastPoint; var newPoint; var scale; var optionsOpen = false; window.addEventListener('message', event => { const type = event.data.type; switch (type) { case 'reset': if (svgImage !== undefined) { scale = 1; viewBox = { x: 0, y: 0, w: svgImage.clientWidth, h: svgImage.clientHeight }; svgImage.setAttribute('viewBox', `0 0 ${svgImage.clientWidth} ${svgImage.clientHeight}`); } break; case 'zoomIn': zoom(true); break; case 'zoomOut': zoom(false); break; case 'params': event.data.params.forEach(addParameterItem); parameterDefinitions = event.data.params; break; case 'svg': const newSvg = event.data.svg; if (svgImage === undefined) { svgContainer.innerHTML = newSvg.replace('<svg', '<svg id="svgImage"'); svgImage = document.getElementById("svgImage"); scale = 1; viewBox = { x: 0, y: 0, w: svgImage.clientWidth, h: svgImage.clientHeight }; svgImage.setAttribute('viewBox', `0 0 ${svgImage.clientWidth} ${svgImage.clientHeight}`); } else { // If we already have an svg element, replace the contents svgImage.innerHTML = newSvg.match(/(?<=<svg(?:.|\n|\r)+?>)(?:(?:.|\n|\r)+)(?=<\/svg>)/)[0]; } break; case 'allData': if (svgImage === undefined && event.data.svg) { // Set svg again svgContainer.innerHTML = event.data.svg.replace('<svg', '<svg id="svgImage"'); svgImage = document.getElementById("svgImage"); scale = 1; viewBox = { x: 0, y: 0, w: svgImage.clientWidth, h: svgImage.clientHeight }; svgImage.setAttribute('viewBox', `0 0 ${svgImage.clientWidth} ${svgImage.clientHeight}`); } if (paramList.innerHTML === '') { // Set parameters again event.data.params.forEach(addParameterItem); parameterDefinitions = event.data.params; // Set all the updated values const values = event.data.values; for (const entry of values) { const id = entry[0]; const value = entry[1]; const valueElem = document.getElementById('value-' + id); if (valueElem.type === 'checkbox') { valueElem.checked = value; } else { valueElem.value = value; } } } if (event.data.optionsOpen) { paramContainer.style.maxHeight = '450px'; } else { paramContainer.style.maxHeight = '0px'; } break; } }); function resetParams() { if (parameterDefinitions) { parameterDefinitions.forEach(param => { const valueElem = document.getElementById("value-" + param.id); switch (param.type.valueType) { case 'String': valueElem.value = param.defaultValue; break; case 'Boolean': valueElem.checked = param.defaultValue; break; default: console.log("OKAY WHAT THE FUCK IS THIS TYPE??? " + param.type.valueType); break; } }); vscode.postMessage({ type: 'paramReset', }); } } function addParameterItem(param) { const li = document.createElement("li"); const nameBox = document.createElement("label"); nameBox.id = "name-" + param.id; nameBox.appendChild(document.createTextNode(param.name)); nameBox.classList.add("name"); nameBox.title = param.description; li.appendChild(nameBox); const valueBox = document.createElement("input"); valueBox.id = "value-" + param.id; switch (param.type.valueType) { case 'String': valueBox.value = param.defaultValue; valueBox.type = 'text'; valueBox.addEventListener("input", e => { vscode.postMessage({ type: 'paramUpdate', id: param.id, value: valueBox.value }); }); break; case 'Boolean': valueBox.checked = param.defaultValue; valueBox.type = 'checkbox'; nameBox.style.cursor = 'pointer'; nameBox.onclick = () => { valueBox.checked = !valueBox.checked; vscode.postMessage({ type: 'paramUpdate', id: param.id, value: valueBox.checked }); }; valueBox.addEventListener("input", e => { vscode.postMessage({ type: 'paramUpdate', id: param.id, value: valueBox.checked }); }); break; default: console.log("OKAY WHAT THE FUCK IS THIS TYPE??? " + param.type.valueType); break; }; // if (type === "Enum") { // /** // * @type {HTMLSelectElement} // */ // const valueBox = document.createElement("select"); // valueBox.id = "value-" + name; // valueBox.classList.add("value"); // for (const value of possibleValues) { // const option = document.createElement("option"); // option.value = value; // option.text = value; // valueBox.appendChild(option); // } // valueBox.value = value; // valueBox.addEventListener("input", _ => { // let oldState = vscode.getState(); // for (const tool of oldState.parameters) { // if (tool.toolName === oldState.currentTool) { // for (const parameter of tool.parameters) { // if (parameter.id === name) { // parameter.value = valueBox.options[valueBox.selectedIndex].value; // break; // } // } // break; // } // } // vscode.setState({ tools: oldState.tools, documentVars: oldState.documentVars, parameters: oldState.parameters, currentUri: oldState.currentUri, currentTool: oldState.currentTool }); // }); // li.appendChild(valueBox); // } else { li.appendChild(valueBox); // } paramList.appendChild(li); } document.getElementById("openOptions").onclick = () => { paramContainer.style.maxHeight = `${Math.min(window.innerHeight - 20, 450)}px`; paramList.style.maxHeight = `${Math.min(window.innerHeight - 60, 410)}px`; optionsOpen = !optionsOpen; vscode.postMessage({ type: 'toggleOptions', }); }; document.getElementById("closeOptions").onclick = () => { paramContainer.style.maxHeight = '0px'; optionsOpen = !optionsOpen; vscode.postMessage({ type: 'toggleOptions', }); }; document.getElementById("revert").onclick = resetParams; // 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', () => { if (svgImage !== undefined) { viewBox.w = svgImage.clientWidth / scale; viewBox.h = svgImage.clientHeight / scale; svgImage.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.w} ${viewBox.h}`); } if (optionsOpen) { paramContainer.style.maxHeight = `${Math.min(window.innerHeight - 20, 450)}px`; paramList.style.maxHeight = `${Math.min(window.innerHeight - 60, 410)}px`; } }); function zoom(zoomIn) { if (svgImage !== undefined) { var w = viewBox.w; var h = viewBox.h; var mx = svgImage.clientWidth / 2;//middle of screen var my = svgImage.clientHeight / 2; var dw = w * 0.15 * (zoomIn ? 1 : -1); var dh = h * 0.15 * (zoomIn ? 1 : -1); var svgSize = { w: svgImage.clientWidth, h: svgImage.clientHeight }; var dx = dw * mx / svgSize.w; var dy = dh * my / svgSize.h; viewBox = { x: viewBox.x + dx, y: viewBox.y + dy, w: viewBox.w - dw, h: viewBox.h - dh }; scale = svgSize.w / viewBox.w; svgImage.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.w} ${viewBox.h}`); } } svgContainer.onmousewheel = (e) => { if (svgImage !== undefined) { var w = viewBox.w; var h = viewBox.h; var mx = e.offsetX; //mouse x var my = e.offsetY; var dw = w * Math.sign(-e.deltaY) * 0.15; var dh = h * Math.sign(-e.deltaY) * 0.15; var svgSize = { w: svgImage.clientWidth, h: svgImage.clientHeight }; var dx = dw * mx / svgSize.w; var dy = dh * my / svgSize.h; viewBox = { x: viewBox.x + dx, y: viewBox.y + dy, w: viewBox.w - dw, h: viewBox.h - dh }; scale = svgSize.w / viewBox.w; svgImage.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.w} ${viewBox.h}`); } }; svgContainer.onmousedown = (e) => { if (svgImage !== undefined && e.button !== 1) { lastPoint = { x: e.x, y: e.y }; document.onmousemove = (e) => { newPoint = { x: e.x, y: e.y }; viewBox.x += (lastPoint.x - newPoint.x) / scale; viewBox.y += (lastPoint.y - newPoint.y) / scale; svgImage.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.w} ${viewBox.h}`); lastPoint = newPoint; }; document.onmouseup = () => { document.onmousemove = null; }; } };