From 22558f4dcbbc9121ef48440ff88a5c41a408fd79 Mon Sep 17 00:00:00 2001 From: yasanthaniroshan Date: Mon, 15 Apr 2024 20:11:01 +0530 Subject: [PATCH] Added Major Changes - Changed the way of interpreting python code (Used worker instead of main thread) - Changed the colour themes of blocks execpt varables,functions - Changed navbar background colour - Added configurations for worker - Added Clear buttom for the terminal output --- Frontend/Blocks/block_definitions.js | 64 +++++++++---------- Frontend/index.html | 80 ++++++++++++++---------- Frontend/scripts/script.js | 93 +++++++++++++++++----------- Frontend/scripts/worker.js | 48 ++++++++++++++ Frontend/styles/styles.css | 29 +++++++-- 5 files changed, 206 insertions(+), 108 deletions(-) create mode 100644 Frontend/scripts/worker.js diff --git a/Frontend/Blocks/block_definitions.js b/Frontend/Blocks/block_definitions.js index dad911d..c145c2c 100644 --- a/Frontend/Blocks/block_definitions.js +++ b/Frontend/Blocks/block_definitions.js @@ -3,7 +3,7 @@ Blockly.Blocks['string_block'] = { this.appendDummyInput() .appendField(new Blockly.FieldTextInput("Hello World!"), "input"); this.setOutput(true, null); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -18,7 +18,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck(null); this.setOutput(true, null); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -33,7 +33,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck(null); this.setOutput(true, null); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -46,7 +46,7 @@ Blockly.Blocks['string_block'] = { .appendField("print"); this.setPreviousStatement(true, null); this.setNextStatement(true, null); - this.setColour(260); + this.setColour('#4C97FF'); this.setTooltip(""); this.setHelpUrl(""); } @@ -63,7 +63,7 @@ Blockly.Blocks['string_block'] = { .appendField("then"); this.setPreviousStatement(true, null); this.setNextStatement(true, null); - this.setColour(65); + this.setColour('#FFBF00'); this.setTooltip(""); this.setHelpUrl(""); } @@ -74,7 +74,7 @@ Blockly.Blocks['string_block'] = { this.appendDummyInput() .appendField(new Blockly.FieldNumber(0), "input"); this.setOutput(true, "Number"); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -89,7 +89,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck(null); this.setOutput(true, "Boolean"); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -108,7 +108,7 @@ Blockly.Blocks['string_block'] = { .appendField("else"); this.setPreviousStatement(true, null); this.setNextStatement(true, null); - this.setColour(65); + this.setColour('#FFAB19'); this.setTooltip(""); this.setHelpUrl(""); } @@ -123,7 +123,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck("Number"); this.setOutput(true, null); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -138,7 +138,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck(null); this.setOutput(true, null); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -153,7 +153,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck(null); this.setOutput(true, "Boolean"); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -172,7 +172,7 @@ Blockly.Blocks['string_block'] = { .appendField("else"); this.setPreviousStatement(true, null); this.setNextStatement(true, null); - this.setColour(65); + this.setColour('#FFBF00'); this.setTooltip(""); this.setHelpUrl(""); } @@ -187,7 +187,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck("Number"); this.setOutput(true, null); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -202,7 +202,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck(null); this.setOutput(true, null); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -218,7 +218,7 @@ Blockly.Blocks['string_block'] = { .appendField("do"); this.setPreviousStatement(true, null); this.setNextStatement(true, null); - this.setColour(65); + this.setColour('#FFBF00'); this.setTooltip(""); this.setHelpUrl(""); } @@ -233,7 +233,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck(null); this.setOutput(true, "Boolean"); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -248,7 +248,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck(null); this.setOutput(true, "Boolean"); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -263,7 +263,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck(null); this.setOutput(true, "Boolean"); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -278,7 +278,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck(null); this.setOutput(true, "Boolean"); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -290,7 +290,7 @@ Blockly.Blocks['string_block'] = { .appendField("input") .appendField(new Blockly.FieldTextInput("prompt"), "input"); this.setOutput(true, "String"); - this.setColour(260); + this.setColour('#4C97FF'); this.setTooltip(""); this.setHelpUrl(""); } @@ -301,7 +301,7 @@ Blockly.Blocks['string_block'] = { this.appendDummyInput() .appendField("True"); this.setOutput(true, "Boolean"); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -312,7 +312,7 @@ Blockly.Blocks['string_block'] = { this.appendDummyInput() .appendField("False"); this.setOutput(true, "Boolean"); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -327,7 +327,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck("Number"); this.setOutput(true, null); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -342,7 +342,7 @@ Blockly.Blocks['string_block'] = { this.appendValueInput("right") .setCheck("Number"); this.setOutput(true, null); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -362,7 +362,7 @@ Blockly.Blocks['string_block'] = { .setCheck(null) .appendField("step"); this.setOutput(true, null); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } @@ -379,7 +379,7 @@ Blockly.Blocks['string_block'] = { .setCheck(null); this.setPreviousStatement(true, null); this.setNextStatement(true, null); - this.setColour(65); + this.setColour('#FFBF00'); this.setTooltip(""); this.setHelpUrl(""); } @@ -391,7 +391,7 @@ Blockly.Blocks['string_block'] = { .appendField("list") .appendField(new Blockly.FieldTextInput("1,2,3"), "input"); this.setOutput(true, null); - this.setColour(160); + this.setColour('#CF63CF'); this.setTooltip(""); this.setHelpUrl(""); } @@ -409,7 +409,7 @@ Blockly.Blocks['string_block'] = { .setCheck(null); this.setPreviousStatement(true, null); this.setNextStatement(true, null); - this.setColour(160); + this.setColour('#CF63CF'); this.setTooltip(""); this.setHelpUrl(""); } @@ -423,7 +423,7 @@ Blockly.Blocks['string_block'] = { .appendField(new Blockly.FieldNumber(0, 0, Infinity, 1), "index") .appendField("of"); this.setOutput(true, null); - this.setColour(160); + this.setColour('#CF63CF'); this.setTooltip(""); this.setHelpUrl(""); } @@ -441,7 +441,7 @@ Blockly.Blocks['string_block'] = { .appendField(new Blockly.FieldTextInput("1,2,3"), "value"); this.setPreviousStatement(true, null); this.setNextStatement(true, null); - this.setColour(160); + this.setColour('#CF63CF'); this.setTooltip(""); this.setHelpUrl(""); } @@ -459,7 +459,7 @@ Blockly.Blocks['string_block'] = { .setCheck(null); this.setPreviousStatement(true, null); this.setNextStatement(true, null); - this.setColour(160); + this.setColour('#CF63CF'); this.setTooltip(""); this.setHelpUrl(""); } @@ -471,7 +471,7 @@ Blockly.Blocks['string_block'] = { .appendField("str") .appendField(new Blockly.FieldNumber(0, 0, Infinity, 1), "number") this.setOutput(true, null); - this.setColour(120); + this.setColour('#59C059'); this.setTooltip(""); this.setHelpUrl(""); } diff --git a/Frontend/index.html b/Frontend/index.html index ccab0ee..e17e0de 100644 --- a/Frontend/index.html +++ b/Frontend/index.html @@ -21,6 +21,34 @@ @@ -100,8 +103,9 @@

Python Code

- Run - Copy + Run + Copy
@@ -114,8 +118,16 @@
-

Output

- +
+

Output

+
+ Clear +
+
+
+ +
diff --git a/Frontend/scripts/script.js b/Frontend/scripts/script.js index 127d10c..33ede8e 100644 --- a/Frontend/scripts/script.js +++ b/Frontend/scripts/script.js @@ -1,5 +1,6 @@ const copyButton = document.getElementById('copy-button'); const runcodeButton = document.getElementById('run-button'); +const clearButton = document.getElementById('clear-button'); const runButtonIcon = document.getElementById('run-icon'); const runButtonText = document.getElementById('run-text'); const codeGenerated = document.getElementById('output'); @@ -11,7 +12,22 @@ loadingIcon.className = 'material-icons left'; loadingIcon.innerHTML = 'cycle'; let pyodide; - +const blockStyles = { + 'Operators': { + 'colourPrimary': '#4a148c', + 'colourSecondary': '#AD7BE9', + 'colourTertiary': '#CDB6E9' + }, + 'Control': { + 'colourPrimary': '#01579b', + 'colourSecondary': '#64C7FF', + 'colourTertiary': '#C5EAFF' + } +} +const theme = Blockly.Theme.defineTheme('mytheme', { + 'base': Blockly.Themes.Classic, + 'blockStyles': blockStyles +}); var options = { toolbox: toolbox, @@ -36,7 +52,6 @@ var options = { }, zoom: { controls: true, - wheel: true, startScale: 1, maxScale: 1.5, minScale: 0.7, @@ -58,27 +73,30 @@ class CustomCategory extends Blockly.ToolboxCategory { addColourBorder_(colour) { this.rowDiv_.style.backgroundColor = colour; } - setSelected(isSelected){ + setSelected(isSelected) { // We do not store the label span on the category, so use getElementsByClassName. var labelDom = this.rowDiv_.getElementsByClassName('blocklyTreeLabel')[0]; if (isSelected) { - // Change the background color of the div to white. - this.rowDiv_.style.backgroundColor = 'white'; - // Set the colour of the text to the colour of the category. - labelDom.style.color = this.colour_; - this.iconDom_.style.color = this.colour_; + // Change the background color of the div to white. + this.rowDiv_.style.backgroundColor = 'white'; + // Set the colour of the text to the colour of the category. + labelDom.style.color = this.colour_; + this.iconDom_.style.color = this.colour_; } else { - // Set the background back to the original colour. - this.rowDiv_.style.backgroundColor = this.colour_; - // Set the text back to white. - labelDom.style.color = 'white'; - this.iconDom_.style.color = 'white'; + // Set the background back to the original colour. + this.rowDiv_.style.backgroundColor = this.colour_; + // Set the text back to white. + labelDom.style.color = 'white'; + this.iconDom_.style.color = 'white'; } // This is used for accessibility purposes. - Blockly.utils.aria.setState(/** @type {!Element} */ (this.htmlDiv_), + Blockly.utils.aria.setState(/** @type {!Element} */(this.htmlDiv_), Blockly.utils.aria.State.SELECTED, isSelected); - } + } } + +const worker = new Worker('scripts/worker.js'); + Blockly.registry.register( Blockly.registry.Type.TOOLBOX_ITEM, Blockly.ToolboxCategory.registrationName, @@ -87,8 +105,8 @@ Blockly.registry.register( var workspace = Blockly.inject("editor", options); var workspaceBlocks = document.getElementById("workspaceBlocks"); -Blockly.utils.colour.setHsvSaturation(0.54); -Blockly.utils.colour.setHsvValue(0.75); + +Blockly.Xml.domToWorkspace(workspaceBlocks, workspace); const supportedEvents = new Set([ Blockly.Events.BLOCK_CHANGE, @@ -105,7 +123,7 @@ function updateCode(event) { } const code = python.pythonGenerator.workspaceToCode(workspace); codeGenerated.innerHTML = code; - preCode.innerHTML = codeGenerated.innerHTML; + preCode.innerHTML = code; console.log(code); hljs.highlightAll(); } @@ -115,8 +133,8 @@ async function runcode() { try { runcodeButton.setAttribute('disabled', true); runButtonText.innerHTML = 'Running'; - let code = codeGenerated.innerHTML; - let output = pyodide.runPython(code); + let code = codeGenerated.innerText; + worker.postMessage({code:code,command:'run'}); runcodeButton.removeAttribute('disabled'); runButtonText.innerHTML = 'Run'; } catch (err) { @@ -143,23 +161,26 @@ runcodeButton.addEventListener('click', () => { runcode(); }); -document.addEventListener('DOMContentLoaded', async () => { - try { - runcodeButton.setAttribute('disabled', true); - runcodeButton.style.width = '6rem'; - runcodeButton.isdisabled = true; - runButtonText.innerHTML = 'Loading...'; - runButtonIcon.className = 'fa fa-spinner'; - pyodide = await loadPyodide(); - runcodeButton.removeAttribute('disabled'); - runcodeButton.style.width = '4rem'; - runButtonText.innerHTML = 'Run'; - runButtonIcon.className = 'fa fa-play'; - terminal.innerHTML += 'Python 3.10 \n>>> ' - pyodide.setStdout({ batched: (msg) => terminal.innerHTML += msg + '\n>>> ' }); - } catch (err) { - console.error('Failed to load Pyodide:', err); +clearButton.addEventListener('click', () => { + terminal.innerHTML = 'Python 3.10 \n>>> '; +}); + + +worker.onerror = function (event) { + console.error('Worker error: ', event.message, event.filename, event.lineno); +}; + +worker.onmessage = function (event) { + if (event.data) { + terminal.innerHTML += event.data.result + '\n>>> '; } +}; + + + + +document.addEventListener('DOMContentLoaded', async () => { + worker.postMessage({command:'start',code:''}); }); workspace.addChangeListener(updateCode); \ No newline at end of file diff --git a/Frontend/scripts/worker.js b/Frontend/scripts/worker.js new file mode 100644 index 0000000..b875d94 --- /dev/null +++ b/Frontend/scripts/worker.js @@ -0,0 +1,48 @@ +// Inside webworker.js +let isready = false; +let pydiode = null; +let buffer = new Array(); + +if ('undefined' === typeof window) { + importScripts('https://cdn.jsdelivr.net/pyodide/v0.24.0/full/pyodide.js'); +} +function stdoutHandler(x) { + self.postMessage({result: x}); +} + +let response = async () => { + let pyodide = await loadPyodide(); + self.pyodide = pyodide; + self.pyodide.setStdout({batched:(x) => stdoutHandler(x)}); + isready = true; +} + +async function codeRunner(code) { + if (!isready) { + await response(); + } + return self.pyodide.runPythonAsync(code); + } + +self.onmessage = async function (event) { + + let command = event.data.command; + if (command === 'run') { + let code = event.data.code; + try { + codeRunner(code); + } catch (err) { + console.error('Error running code:', err); + } + } + else if (command === 'start') + { + let code = event.data.code; + try { + await codeRunner(code); + self.postMessage({result: 'Python 3.10'}); + } catch (err) { + console.error('Error running code:', err); + } + } +}; diff --git a/Frontend/styles/styles.css b/Frontend/styles/styles.css index db9dc1b..14cafe2 100644 --- a/Frontend/styles/styles.css +++ b/Frontend/styles/styles.css @@ -5,7 +5,7 @@ flex-direction: row; justify-content: space-between; align-items: center; - background-color:#1f63a3ec; + background-color:#184772ec; margin: 0; padding: 0; } @@ -113,8 +113,14 @@ background-color: #f3f3f3; width: 100%; height: 100%; -} + max-height: 35rem; + overflow-y: auto; +} +.python +{ + display: block; +} .output { grid-area: output; background-color: white; @@ -123,13 +129,20 @@ box-shadow: 2px 3px 18px 0px rgba(0, 0, 0, 0.34); padding: 0.2rem; margin-right: 0.5rem; - + overflow-y: auto; } .output-title { margin: 1rem; font-weight: 500; +} + +.terminal-output-div +{ + overflow-y: visible; + max-height: 10rem; + } .terminal-output { @@ -139,15 +152,19 @@ height: 70%; resize: none; border: none; + display: block; + } -.terminal-output::-webkit-scrollbar { - width: 0.5rem; -} + .terminal-output:focus{ border: 0 none #FFF; overflow: hidden; outline:none; } +#clear-button:hover { + background-color: #DB9E14; +} + .container { display: grid;