// Most Listeners are stored here function startListeners() { window.addEventListener('keyup', function(e) { scheduleUpdate(1); simulationArea.shiftDown = e.shiftKey; if (e.keyCode == 16) { simulationArea.shiftDown = false; } if (e.key == "Meta" || e.key == "Control") { simulationArea.controlDown = false; } }); document.getElementById("simulationArea").addEventListener('mousedown', function(e) { createNode = true stopWire = false simulationArea.mouseDown = true; $("input").blur(); errorDetected = false; updateSimulation = true; updatePosition = true; updateCanvas = true; simulationArea.lastSelected = undefined; simulationArea.selected = false; simulationArea.hover = undefined; var rect = simulationArea.canvas.getBoundingClientRect(); simulationArea.mouseDownRawX = (e.clientX - rect.left) * DPR; simulationArea.mouseDownRawY = (e.clientY - rect.top) * DPR; simulationArea.mouseDownX = Math.round(((simulationArea.mouseDownRawX - globalScope.ox) / globalScope.scale) / unit) * unit; simulationArea.mouseDownY = Math.round(((simulationArea.mouseDownRawY - globalScope.oy) / globalScope.scale) / unit) * unit; simulationArea.oldx = globalScope.ox; simulationArea.oldy = globalScope.oy; e.preventDefault(); scheduleBackup(); scheduleUpdate(1); $('.dropdown.open').removeClass('open'); }); document.getElementById("simulationArea").addEventListener('mouseup', function(e) { if (simulationArea.lastSelected) simulationArea.lastSelected.newElement = false; /* handling restricted circuit elements */ if(simulationArea.lastSelected && restrictedElements.includes(simulationArea.lastSelected.objectType) && !globalScope.restrictedCircuitElementsUsed.includes(simulationArea.lastSelected.objectType)) { globalScope.restrictedCircuitElementsUsed.push(simulationArea.lastSelected.objectType); updateRestrictedElementsList(); } // deselect multible elements with click if (!simulationArea.shiftDown && simulationArea.multipleObjectSelections.length > 0 ) { if ( !simulationArea.multipleObjectSelections.includes( simulationArea.lastSelected ) ) simulationArea.multipleObjectSelections = []; } }); window.addEventListener('mousemove', onMouseMove); window.addEventListener('keydown', function(e) { if(document.activeElement.tagName == "INPUT") return; if(listenToSimulator){ // If mouse is focusing on input element, then override any action // if($(':focus').length){ // return; // } if (document.activeElement.tagName == "INPUT" || simulationArea.mouseRawX < 0 || simulationArea.mouseRawY < 0 || simulationArea.mouseRawX > width || simulationArea.mouseRawY > height) { return; } else { // HACK TO REMOVE FOCUS ON PROPERTIES if (document.activeElement.type == "number") { hideProperties(); showProperties(simulationArea.lastSelected) } } errorDetected = false; updateSimulation = true; updatePosition = true; simulationArea.shiftDown = e.shiftKey; // stop making wires when we connect the 2nd termial to a node if(stopWire){ createNode=false } if (e.key == "Meta" || e.key == "Control") { simulationArea.controlDown = true; } // zoom in (+) if ((simulationArea.controlDown && (e.keyCode == 187 || e.keyCode == 171))||e.keyCode==107) { e.preventDefault(); ZoomIn() } // zoom out (-) if ((simulationArea.controlDown && (e.keyCode == 189 || e.keyCode == 173))||e.keyCode==109) { e.preventDefault(); ZoomOut() } if (simulationArea.mouseRawX < 0 || simulationArea.mouseRawY < 0 || simulationArea.mouseRawX > width || simulationArea.mouseRawY > height) return; scheduleUpdate(1); updateCanvas = true; wireToBeChecked = 1; // Needs to be deprecated, moved to more recent listeners if (simulationArea.controlDown && (e.key == "C" || e.key == "c")) { // simulationArea.copyList=simulationArea.multipleObjectSelections.slice(); // if(simulationArea.lastSelected&&simulationArea.lastSelected!==simulationArea.root&&!simulationArea.copyList.contains(simulationArea.lastSelected)){ // simulationArea.copyList.push(simulationArea.lastSelected); // } // copy(simulationArea.copyList); } if (simulationArea.lastSelected && simulationArea.lastSelected.keyDown) { if (e.key.toString().length == 1 || e.key.toString() == "Backspace") { simulationArea.lastSelected.keyDown(e.key.toString()); return; } } if (simulationArea.lastSelected && simulationArea.lastSelected.keyDown2) { if (e.key.toString().length == 1) { simulationArea.lastSelected.keyDown2(e.key.toString()); return; } } if (simulationArea.lastSelected && simulationArea.lastSelected.keyDown3) { if (e.key.toString() != "Backspace" && e.key.toString() != "Delete") { simulationArea.lastSelected.keyDown3(e.key.toString()); return; } } if (e.keyCode == 16) { simulationArea.shiftDown = true; if (simulationArea.lastSelected && !simulationArea.lastSelected.keyDown && simulationArea.lastSelected.objectType != "Wire" && simulationArea.lastSelected.objectType != "CircuitElement" && !simulationArea.multipleObjectSelections.contains(simulationArea.lastSelected)) { simulationArea.multipleObjectSelections.push(simulationArea.lastSelected); } } if (e.keyCode == 8 || e.key == "Delete") { delete_selected(); } if (simulationArea.controlDown && e.key.charCodeAt(0) == 122) { // detect the special CTRL-Z code undo(); } // Detect online save shortcut (CTRL+S) if (simulationArea.controlDown && e.keyCode == 83 && !simulationArea.shiftDown) { save(); e.preventDefault(); } // Detect offline save shortcut (CTRL+SHIFT+S) if (simulationArea.controlDown && e.keyCode == 83 && simulationArea.shiftDown) { saveOffline(); e.preventDefault(); } // Detect Select all Shortcut if (simulationArea.controlDown && (e.keyCode == 65 || e.keyCode == 97)) { selectAll(); e.preventDefault(); } //deselect all Shortcut if (e.keyCode == 27) { simulationArea.multipleObjectSelections = []; simulationArea.lastSelected = undefined; e.preventDefault(); } //change direction fns if (simulationArea.lastSelected != undefined) { let direction = ""; switch (e.keyCode) { case 37: case 65: direction = "LEFT"; break; case 38: case 87: direction = "UP"; break; case 39: case 68: direction = "RIGHT"; break; case 40: case 83: direction = "DOWN"; break; default: break; } if (direction !== ""){ simulationArea.lastSelected.newDirection(direction); } } if ((e.keyCode == 113 || e.keyCode == 81) && simulationArea.lastSelected != undefined) { if (simulationArea.lastSelected.bitWidth !== undefined) simulationArea.lastSelected.newBitWidth(parseInt(prompt("Enter new bitWidth"), 10)); } if (simulationArea.controlDown && (e.key == "T" || e.key == "t")) { // e.preventDefault(); //browsers normally open a new tab simulationArea.changeClockTime(prompt("Enter Time:")); } // f1 key for opening the documentation page if (e.keyCode === 112) { e.preventDefault(); window.open('https://docs.circuitverse.org/', '_blank'); } } }) document.getElementById("simulationArea").addEventListener('dblclick', function(e) { scheduleUpdate(2); if (simulationArea.lastSelected && simulationArea.lastSelected.dblclick !== undefined) { simulationArea.lastSelected.dblclick(); } // not needed becasue we do that with one click , but leaving it as it is will not harm if (!simulationArea.shiftDown) { simulationArea.multipleObjectSelections = []; } }); window.addEventListener('mouseup', onMouseUp); document.getElementById("simulationArea").addEventListener('mousewheel', MouseScroll); document.getElementById("simulationArea").addEventListener('DOMMouseScroll', MouseScroll); function MouseScroll(event) { event.preventDefault() var deltaY = event.wheelDelta ? event.wheelDelta : -event.detail;   event.preventDefault();   var deltaY = event.wheelDelta ? event.wheelDelta : -event.detail;   let direction = deltaY > 0 ? 1 : -1;   handleZoom(direction); updateCanvas = true; if(layoutMode)layoutUpdate(); else update(); // Schedule update not working, this is INEFFICIENT } document.addEventListener('cut', function(e) { if(document.activeElement.tagName == "INPUT") return; if(listenToSimulator){ simulationArea.copyList = simulationArea.multipleObjectSelections.slice(); if (simulationArea.lastSelected && simulationArea.lastSelected !== simulationArea.root && !simulationArea.copyList.contains(simulationArea.lastSelected)) { simulationArea.copyList.push(simulationArea.lastSelected); } var textToPutOnClipboard = copy(simulationArea.copyList, true); // Updated restricted elements updateRestrictedElementsInScope(); localStorage.setItem('clipboardData', textToPutOnClipboard); e.preventDefault(); if(textToPutOnClipboard==undefined) return; if (isIe) { window.clipboardData.setData('Text', textToPutOnClipboard); } else { e.clipboardData.setData('text/plain', textToPutOnClipboard); } } }); document.addEventListener('copy', function(e) { if(document.activeElement.tagName == "INPUT") return; if(listenToSimulator){ simulationArea.copyList = simulationArea.multipleObjectSelections.slice(); if (simulationArea.lastSelected && simulationArea.lastSelected !== simulationArea.root && !simulationArea.copyList.contains(simulationArea.lastSelected)) { simulationArea.copyList.push(simulationArea.lastSelected); } var textToPutOnClipboard = copy(simulationArea.copyList); // Updated restricted elements updateRestrictedElementsInScope(); localStorage.setItem('clipboardData', textToPutOnClipboard); e.preventDefault(); if(textToPutOnClipboard==undefined) return; if (isIe) { window.clipboardData.setData('Text', textToPutOnClipboard); } else { e.clipboardData.setData('text/plain', textToPutOnClipboard); } } }); document.addEventListener('paste', function(e) { if(document.activeElement.tagName == "INPUT") return; if(listenToSimulator){ var data; if (isIe) { data = window.clipboardData.getData('Text'); } else { data = e.clipboardData.getData('text/plain'); } paste(data); // Updated restricted elements updateRestrictedElementsInScope(); e.preventDefault(); } }); restrictedElements.forEach((element) => { $(`#${element}`).mouseover(() => { showRestricted(); }); $(`#${element}`).mouseout(() => { hideRestricted(); }) }); } var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") != -1 || navigator.userAgent.toLowerCase().indexOf("trident") != -1); function removeMiniMap() { if (lightMode) return; if (simulationArea.lastSelected == globalScope.root && simulationArea.mouseDown) return; if (lastMiniMapShown + 2000 >= new Date().getTime()) { setTimeout(removeMiniMap, lastMiniMapShown + 2000 - new Date().getTime()); return; } $('#miniMap').fadeOut('fast'); } function onMouseMove(e) { var rect = simulationArea.canvas.getBoundingClientRect(); simulationArea.mouseRawX = (e.clientX - rect.left) * DPR; simulationArea.mouseRawY = (e.clientY - rect.top) * DPR; simulationArea.mouseXf = (simulationArea.mouseRawX - globalScope.ox) / globalScope.scale; simulationArea.mouseYf = (simulationArea.mouseRawY - globalScope.oy) / globalScope.scale; simulationArea.mouseX = Math.round(simulationArea.mouseXf / unit) * unit; simulationArea.mouseY = Math.round(simulationArea.mouseYf / unit) * unit; updateCanvas = true; if (simulationArea.lastSelected && (simulationArea.mouseDown || simulationArea.lastSelected.newElement)) { updateCanvas = true; var fn; if (simulationArea.lastSelected == globalScope.root) { fn = function() { updateSelectionsAndPane(); } } else { fn = function() { if (simulationArea.lastSelected) simulationArea.lastSelected.update(); }; } scheduleUpdate(0, 20, fn); } else { scheduleUpdate(0, 200); } } function onMouseUp(e) { createNode =simulationArea.controlDown simulationArea.mouseDown = false; if (!lightMode) { lastMiniMapShown = new Date().getTime(); setTimeout(removeMiniMap, 2000); } errorDetected = false; updateSimulation = true; updatePosition = true; updateCanvas = true; gridUpdate = true; wireToBeChecked = true; scheduleUpdate(1); for (var i = 0; i < 2; i++) { updatePosition = true; wireToBeChecked = true; update(); } errorDetected = false; updateSimulation = true; updatePosition = true; updateCanvas = true; gridUpdate = true; wireToBeChecked = true; scheduleUpdate(1); var rect = simulationArea.canvas.getBoundingClientRect(); if (!(simulationArea.mouseRawX < 0 || simulationArea.mouseRawY < 0 || simulationArea.mouseRawX > width || simulationArea.mouseRawY > height)) { smartDropXX = simulationArea.mouseX + 100; //Math.round(((simulationArea.mouseRawX - globalScope.ox+100) / globalScope.scale) / unit) * unit; smartDropYY = simulationArea.mouseY - 50; //Math.round(((simulationArea.mouseRawY - globalScope.oy+100) / globalScope.scale) / unit) * unit; } } function delete_selected(){ $("input").blur(); hideProperties(); if (simulationArea.lastSelected && !(simulationArea.lastSelected.objectType == "Node" && simulationArea.lastSelected.type != 2)) simulationArea.lastSelected.delete(); for (var i = 0; i < simulationArea.multipleObjectSelections.length; i++) { if (!(simulationArea.multipleObjectSelections[i].objectType == "Node" && simulationArea.multipleObjectSelections[i].type != 2)) simulationArea.multipleObjectSelections[i].cleanDelete(); } simulationArea.multipleObjectSelections = []; // Updated restricted elements updateRestrictedElementsInScope(); } function resizeTabs(){ var $windowsize = $('body').width(); var $sideBarsize = $('.side').width(); var $maxwidth = ($windowsize - $sideBarsize); $("#tabsBar div").each(function(e){ $(this).css({ 'max-width': $maxwidth - 30 }); }); } window.addEventListener("resize", resizeTabs); resizeTabs(); $(function () { $('[data-toggle="tooltip"]').tooltip() }); // direction is only 1 or -1 function handleZoom(direction) {   if (globalScope.scale > 0.5 * DPR) {     changeScale(direction * 0.1 * DPR);   } else if (globalScope.scale < 4 * DPR) {     changeScale(direction * 0.1 * DPR);   }   gridUpdate = true; } function ZoomIn() {   handleZoom(1); } function ZoomOut() {   handleZoom(-1); }