mirror of
https://github.com/damp11113-software/ccIDE.git
synced 2025-04-27 22:48:13 +00:00
add splash screen and making library manager
This commit is contained in:
parent
c2d0f4b970
commit
f6f9e02542
BIN
assets/noimagefallback.png
Normal file
BIN
assets/noimagefallback.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
assets/organization-logo.png
Normal file
BIN
assets/organization-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
@ -11,5 +11,5 @@ luaGenerator.forBlock['ide_addcode'] = function(block, generator) {
|
||||
|
||||
// Remove all occurrences of the matched characters
|
||||
const cleanedStr = codefromuser.replace(/[']/g, '');
|
||||
return cleanedStr;
|
||||
return cleanedStr+"\n";
|
||||
};
|
||||
|
@ -9,6 +9,7 @@
|
||||
"peripherals": false,
|
||||
"library": false,
|
||||
"turtle": false,
|
||||
"pocket": false,
|
||||
"require_network": false,
|
||||
"dependencies": {}
|
||||
}
|
87
blocks/Template/block_design.json
Normal file
87
blocks/Template/block_design.json
Normal file
@ -0,0 +1,87 @@
|
||||
{
|
||||
"math_operation": {
|
||||
"message0": "args %1 %2 %3",
|
||||
"args0": [
|
||||
{
|
||||
"type": "field_dropdown",
|
||||
"name": "OPERATOR",
|
||||
"options": [
|
||||
["+", "ADD"],
|
||||
["-", "SUBTRACT"],
|
||||
["*", "MULTIPLY"],
|
||||
["/", "DIVIDE"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "NUM1",
|
||||
"check": "Number"
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "NUM2",
|
||||
"check": "Number"
|
||||
}
|
||||
],
|
||||
"inputsInline": true,
|
||||
"output": "Number",
|
||||
"colour": 230,
|
||||
"tooltip": "Perform a mathematical operation",
|
||||
"helpUrl": ""
|
||||
},
|
||||
"text_print": {
|
||||
"message0": "print %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "TEXT"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 160,
|
||||
"tooltip": "Print text",
|
||||
"helpUrl": ""
|
||||
},
|
||||
"controls_if": {
|
||||
"message0": "if %1 then",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "IF0",
|
||||
"check": "Boolean"
|
||||
}
|
||||
],
|
||||
"message1": "do %1",
|
||||
"args1": [
|
||||
{
|
||||
"type": "input_statement",
|
||||
"name": "DO0"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 210,
|
||||
"tooltip": "If condition",
|
||||
"helpUrl": ""
|
||||
},
|
||||
"variables_set": {
|
||||
"message0": "set %1 to %2",
|
||||
"args0": [
|
||||
{
|
||||
"type": "field_variable",
|
||||
"name": "VAR",
|
||||
"variable": "item"
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "VALUE"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 330,
|
||||
"tooltip": "Set variable",
|
||||
"helpUrl": ""
|
||||
}
|
||||
}
|
58
blocks/Template/generator.js
Normal file
58
blocks/Template/generator.js
Normal file
@ -0,0 +1,58 @@
|
||||
const { luaGenerator } = require('blockly/lua');
|
||||
|
||||
// Check if luaGenerator.forBlock is defined and initialize if necessary
|
||||
if (!luaGenerator.forBlock) {
|
||||
luaGenerator.forBlock = {};
|
||||
}
|
||||
|
||||
// Math operation block
|
||||
luaGenerator.forBlock['math_operation'] = function(block, generator) {
|
||||
var operator = block.getFieldValue('OPERATOR');
|
||||
var num1 = generator.valueToCode(block, 'NUM1', generator.ORDER_ATOMIC);
|
||||
var num2 = generator.valueToCode(block, 'NUM2', generator.ORDER_ATOMIC);
|
||||
|
||||
var operatorSymbol = '';
|
||||
switch (operator) {
|
||||
case 'ADD':
|
||||
operatorSymbol = '+';
|
||||
break;
|
||||
case 'SUBTRACT':
|
||||
operatorSymbol = '-';
|
||||
break;
|
||||
case 'MULTIPLY':
|
||||
operatorSymbol = '*';
|
||||
break;
|
||||
case 'DIVIDE':
|
||||
operatorSymbol = '/';
|
||||
break;
|
||||
default:
|
||||
operatorSymbol = '+';
|
||||
break;
|
||||
}
|
||||
|
||||
var code = `${num1} ${operatorSymbol} ${num2}`;
|
||||
return [code, generator.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
// Print text block
|
||||
luaGenerator.forBlock['text_print'] = function(block, generator) {
|
||||
var text = generator.valueToCode(block, 'TEXT', generator.ORDER_NONE) || '\'\'';
|
||||
var code = `print(${text})\n`;
|
||||
return code;
|
||||
};
|
||||
|
||||
// If condition block
|
||||
luaGenerator.forBlock['controls_if'] = function(block, generator) {
|
||||
var condition = generator.valueToCode(block, 'IF0', generator.ORDER_NONE) || 'false';
|
||||
var branch = generator.statementToCode(block, 'DO0');
|
||||
var code = `if ${condition} then\n${branch}\nend\n`;
|
||||
return code;
|
||||
};
|
||||
|
||||
// Set variable block
|
||||
luaGenerator.forBlock['variables_set'] = function(block, generator) {
|
||||
var variable = generator.nameDB_.getName(block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
|
||||
var value = generator.valueToCode(block, 'VALUE', generator.ORDER_NONE) || '0';
|
||||
var code = `${variable} = ${value}\n`;
|
||||
return code;
|
||||
};
|
@ -1,14 +1,15 @@
|
||||
{
|
||||
"name": "Test Peripheral",
|
||||
"name": "Template",
|
||||
"author": "DPSoftware Foundation",
|
||||
"description": "Test Peripheral",
|
||||
"description": "Template for creating custom blocks in ccIDE",
|
||||
"version": "1.0.0",
|
||||
"category": "Blockly Extensions",
|
||||
"keyword": "test",
|
||||
"category": "",
|
||||
"keyword": "template, custom block, ccIDE",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"peripherals": false,
|
||||
"library": false,
|
||||
"turtle": false,
|
||||
"pocket": false,
|
||||
"require_network": false,
|
||||
"dependencies": {}
|
||||
}
|
44
blocks/Template/toolbox.xml
Normal file
44
blocks/Template/toolbox.xml
Normal file
@ -0,0 +1,44 @@
|
||||
<xml id="toolbox" style="display: none;">
|
||||
<category name="Template" colour="270">
|
||||
<!-- Math operation block -->
|
||||
<block type="math_operation">
|
||||
<value name="NUM1">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">10</field> <!-- Default value -->
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="NUM2">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">5</field> <!-- Default value -->
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
|
||||
<!-- Print text block -->
|
||||
<block type="text_print">
|
||||
<value name="TEXT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">Hello, world!</field> <!-- Default value -->
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
|
||||
<!-- If condition block -->
|
||||
<block type="controls_if">
|
||||
<value name="IF0">
|
||||
<shadow type="logic_boolean">
|
||||
<field name="BOOL">TRUE</field> <!-- Default value -->
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
|
||||
<!-- Set variable block -->
|
||||
<block type="variables_set">
|
||||
<value name="VALUE">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">0</field> <!-- Default value -->
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
</xml>
|
@ -1,32 +0,0 @@
|
||||
{
|
||||
"custom_math_operation": {
|
||||
"message0": "%1 %2 %3",
|
||||
"args0": [
|
||||
{
|
||||
"type": "field_dropdown",
|
||||
"name": "OPERATOR",
|
||||
"options": [
|
||||
["+", "ADD"],
|
||||
["-", "SUBTRACT"],
|
||||
["*", "MULTIPLY"],
|
||||
["/", "DIVIDE"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "NUM1",
|
||||
"check": "Number"
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "NUM2",
|
||||
"check": "Number"
|
||||
}
|
||||
],
|
||||
"inputsInline": true,
|
||||
"output": "Number",
|
||||
"colour": 230,
|
||||
"tooltip": "Perform a mathematical operation",
|
||||
"helpUrl": ""
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
const { luaGenerator } = require('blockly/lua');
|
||||
|
||||
// Check if luaGenerator.forBlock is defined and initialize if necessary-
|
||||
if (!luaGenerator.forBlock) {
|
||||
luaGenerator.forBlock = {};
|
||||
}
|
||||
|
||||
// Define your custom block handler
|
||||
luaGenerator.forBlock['custom_math_operation'] = function(block, generator) {
|
||||
var operator = block.getFieldValue('OPERATOR');
|
||||
var num1 = generator.valueToCode(block, 'NUM1', generator.ORDER_ATOMIC);
|
||||
var num2 = generator.valueToCode(block, 'NUM2', generator.ORDER_ATOMIC);
|
||||
|
||||
var operatorSymbol = '';
|
||||
switch (operator) {
|
||||
case 'ADD':
|
||||
operatorSymbol = '+';
|
||||
break;
|
||||
case 'SUBTRACT':
|
||||
operatorSymbol = '-';
|
||||
break;
|
||||
case 'MULTIPLY':
|
||||
operatorSymbol = '*';
|
||||
break;
|
||||
case 'DIVIDE':
|
||||
operatorSymbol = '/';
|
||||
break;
|
||||
default:
|
||||
operatorSymbol = '+';
|
||||
break;
|
||||
}
|
||||
|
||||
var code = `${num1} ${operatorSymbol} ${num2}`;
|
||||
return [code, generator.ORDER_ATOMIC];
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
<xml id="toolbox" style="display: none;">
|
||||
<category name="Custom Blocks" colour="270">
|
||||
<!-- Define your custom blocks here -->
|
||||
<block type="custom_math_operation">
|
||||
<value name="NUM1">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">10</field> <!-- Default value -->
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="NUM2">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">5</field> <!-- Default value -->
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
</xml>
|
Binary file not shown.
@ -4,32 +4,61 @@ const prompt = require('electron-prompt');
|
||||
const path = require('path');
|
||||
const ipc = ipcMain
|
||||
|
||||
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';
|
||||
|
||||
let currentprojectpath = null;
|
||||
let currentprojectname = null;
|
||||
let currentprojectopen = false
|
||||
let appexiting = false
|
||||
let currentprojectopen = false;
|
||||
let appexiting = false;
|
||||
let appreloading = false;
|
||||
let currentworkspacechange = false;
|
||||
let isopennewproject = false;
|
||||
|
||||
app.whenReady().then(() => {
|
||||
currentprojectpath = null;
|
||||
currentprojectname = null;
|
||||
currentprojectopen = false;
|
||||
appexiting = false;
|
||||
|
||||
reloadall(false);
|
||||
const win = new BrowserWindow({
|
||||
width: 1280,
|
||||
height: 720,
|
||||
icon: path.join(__dirname, '..', 'assets', 'ccIDEIcon.ico'),
|
||||
icon: path.join(__dirname, 'assets', 'ccIDEIcon.ico'),
|
||||
webPreferences: {
|
||||
devTools: true,
|
||||
nodeIntegration: true,
|
||||
enableRemoteModule: true,
|
||||
contextIsolation: false,
|
||||
}
|
||||
},
|
||||
show: false,
|
||||
center: true,
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
//win.openDevTools();
|
||||
win.maximize()
|
||||
var splash = new BrowserWindow({
|
||||
width: 600,
|
||||
height: 300,
|
||||
icon: path.join(__dirname, 'assets', 'ccIDEIcon.ico'),
|
||||
transparent: true,
|
||||
frame: false,
|
||||
center: true
|
||||
});
|
||||
|
||||
win.loadFile('src/index.html');
|
||||
splash.loadFile('src/splash.html');
|
||||
win.setTitle(`ccIDE`)
|
||||
|
||||
|
||||
ipc.once('ready', () => {
|
||||
console.log("ready")
|
||||
if (splash) {
|
||||
splash.close();
|
||||
}
|
||||
win.show();
|
||||
win.maximize();
|
||||
});
|
||||
|
||||
ipc.on('erroronstart', (event, errormessage) => {
|
||||
dialog.showErrorBox("Error on startup", errormessage);
|
||||
//win.openDevTools();
|
||||
});
|
||||
|
||||
|
||||
|
||||
//app.on('activate', () => {
|
||||
// if (BrowserWindow.getAllWindows().length === 0) {
|
||||
@ -37,6 +66,21 @@ app.whenReady().then(() => {
|
||||
// }
|
||||
//})
|
||||
|
||||
function reloadall(isloaded=true) {
|
||||
currentprojectpath = null;
|
||||
currentprojectname = null;
|
||||
currentprojectopen = false;
|
||||
currentworkspacechange = false;
|
||||
appexiting = false;
|
||||
appreloading = false;
|
||||
isopennewproject = false;
|
||||
if (isloaded) {
|
||||
win.setTitle(`ccIDE`)
|
||||
win.reload();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Define a custom menu template
|
||||
const menuTemplate = [
|
||||
{
|
||||
@ -46,43 +90,106 @@ app.whenReady().then(() => {
|
||||
label: 'New',
|
||||
accelerator: 'CmdOrCtrl+N',
|
||||
click: () => {
|
||||
win.reload()
|
||||
if (currentworkspacechange) {
|
||||
const result = dialog.showMessageBoxSync({
|
||||
type: 'question',
|
||||
buttons: ['Save', 'Don\'t Save', 'Cancel'],
|
||||
defaultId: 2,
|
||||
title: 'Save Changes',
|
||||
message: "Your project is not saved",
|
||||
});
|
||||
if (result === 1) {
|
||||
// Don't save
|
||||
reloadall();
|
||||
} else if (result === 0) {
|
||||
// Save
|
||||
appreloading = true;
|
||||
win.webContents.send('save-workspace-request');
|
||||
}
|
||||
} else {
|
||||
reloadall();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Open',
|
||||
accelerator: 'CmdOrCtrl+O',
|
||||
click: () => {
|
||||
dialog.showOpenDialog(win, {
|
||||
title: 'Open Project',
|
||||
defaultPath: app.getPath('documents'),
|
||||
filters: [
|
||||
{ name: 'ComputerCraft Project', extensions: ['ccp'] }
|
||||
],
|
||||
properties: ['openFile']
|
||||
}).then(result => {
|
||||
if (!result.canceled) {
|
||||
const filePath = result.filePaths[0];
|
||||
if (currentworkspacechange) {
|
||||
const result = dialog.showMessageBoxSync({
|
||||
type: 'question',
|
||||
buttons: ['Save', 'Don\'t Save', 'Cancel'],
|
||||
defaultId: 2,
|
||||
title: 'Save Changes',
|
||||
message: "Your project is not saved",
|
||||
});
|
||||
if (result === 1) {
|
||||
// Don't save
|
||||
dialog.showOpenDialog(win, {
|
||||
title: 'Open Project',
|
||||
defaultPath: app.getPath('documents'),
|
||||
filters: [
|
||||
{ name: 'ComputerCraft Project', extensions: ['ccp'] }
|
||||
],
|
||||
properties: ['openFile']
|
||||
}).then(result => {
|
||||
if (!result.canceled) {
|
||||
const filePath = result.filePaths[0];
|
||||
|
||||
fs.readFile(filePath, 'utf8', (err, json) => {
|
||||
if (err) {
|
||||
console.error('Error loading workspace:', err);
|
||||
return;
|
||||
}
|
||||
win.webContents.send('load-workspace', json);
|
||||
|
||||
currentprojectpath = result.filePaths[0]
|
||||
currentprojectname = path.basename(result.filePaths[0]);
|
||||
currentprojectopen = true;
|
||||
|
||||
win.setTitle(`${currentprojectname} | ccIDE`)
|
||||
});
|
||||
|
||||
fs.readFile(filePath, 'utf8', (err, json) => {
|
||||
if (err) {
|
||||
console.error('Error loading workspace:', err);
|
||||
return;
|
||||
}
|
||||
win.webContents.send('load-workspace', json);
|
||||
|
||||
currentprojectpath = result.filePaths[0]
|
||||
currentprojectname = path.basename(result.filePaths[0]);
|
||||
currentprojectopen = true;
|
||||
|
||||
win.setTitle(`${currentprojectname} | ccIDE`)
|
||||
}).catch(err => {
|
||||
console.error('Error showing open dialog:', err);
|
||||
});
|
||||
|
||||
} else if (result === 0) {
|
||||
// Save
|
||||
isopennewproject = true;
|
||||
win.webContents.send('save-workspace-request');
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('Error showing open dialog:', err);
|
||||
});
|
||||
} else {
|
||||
dialog.showOpenDialog(win, {
|
||||
title: 'Open Project',
|
||||
defaultPath: app.getPath('documents'),
|
||||
filters: [
|
||||
{ name: 'ComputerCraft Project', extensions: ['ccp'] }
|
||||
],
|
||||
properties: ['openFile']
|
||||
}).then(result => {
|
||||
if (!result.canceled) {
|
||||
const filePath = result.filePaths[0];
|
||||
|
||||
fs.readFile(filePath, 'utf8', (err, json) => {
|
||||
if (err) {
|
||||
console.error('Error loading workspace:', err);
|
||||
return;
|
||||
}
|
||||
win.webContents.send('load-workspace', json);
|
||||
|
||||
currentprojectpath = result.filePaths[0]
|
||||
currentprojectname = path.basename(result.filePaths[0]);
|
||||
currentprojectopen = true;
|
||||
|
||||
win.setTitle(`${currentprojectname} | ccIDE`)
|
||||
});
|
||||
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('Error showing open dialog:', err);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -133,7 +240,7 @@ app.whenReady().then(() => {
|
||||
{
|
||||
label: 'About',
|
||||
click: () => {
|
||||
console.log('About clicked');
|
||||
win.webContents.send("open-about")
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -194,6 +301,9 @@ app.whenReady().then(() => {
|
||||
win.webContents.send('workspace-saved', true);
|
||||
|
||||
win.setTitle(`${currentprojectname} | ccIDE`)
|
||||
if (currentworkspacechange) {
|
||||
currentworkspacechange = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -217,9 +327,47 @@ app.whenReady().then(() => {
|
||||
|
||||
win.setTitle(`${currentprojectname} | ccIDE`)
|
||||
|
||||
if (currentworkspacechange) {
|
||||
currentworkspacechange = false;
|
||||
}
|
||||
|
||||
if (appexiting) {
|
||||
app.quit();
|
||||
}
|
||||
if (appreloading) {
|
||||
reloadall();
|
||||
}
|
||||
if (isopennewproject) {
|
||||
dialog.showOpenDialog(win, {
|
||||
title: 'Open Project',
|
||||
defaultPath: app.getPath('documents'),
|
||||
filters: [
|
||||
{ name: 'ComputerCraft Project', extensions: ['ccp'] }
|
||||
],
|
||||
properties: ['openFile']
|
||||
}).then(result => {
|
||||
if (!result.canceled) {
|
||||
const filePath = result.filePaths[0];
|
||||
|
||||
fs.readFile(filePath, 'utf8', (err, json) => {
|
||||
if (err) {
|
||||
console.error('Error loading workspace:', err);
|
||||
return;
|
||||
}
|
||||
win.webContents.send('load-workspace', json);
|
||||
|
||||
currentprojectpath = result.filePaths[0]
|
||||
currentprojectname = path.basename(result.filePaths[0]);
|
||||
currentprojectopen = true;
|
||||
|
||||
win.setTitle(`${currentprojectname} | ccIDE`)
|
||||
});
|
||||
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('Error showing open dialog:', err);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -227,6 +375,10 @@ app.whenReady().then(() => {
|
||||
|
||||
ipc.on('workspace-notsave', (event) => {
|
||||
win.setTitle(`${currentprojectname}* | ccIDE`)
|
||||
currentworkspacechange = true;
|
||||
})
|
||||
ipc.on('workspace-unsave', (event) => {
|
||||
currentworkspacechange = true;
|
||||
})
|
||||
})
|
||||
|
||||
@ -258,3 +410,9 @@ app.on("close", function(e) {
|
||||
win = null;
|
||||
}
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
168
package-lock.json
generated
168
package-lock.json
generated
@ -9,39 +9,23 @@
|
||||
"version": "1.0.2",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@blockly/field-multilineinput": "^5.0.5",
|
||||
"@blockly/theme-dark": "^7.0.3",
|
||||
"@electron-fonts/noto-sans": "^1.2.0",
|
||||
"@electron/remote": "^2.1.2",
|
||||
"blockly": "^11.1.1",
|
||||
"bootstrap": "^5.3.3",
|
||||
"electron-prompt": "^1.7.0",
|
||||
"mergexml": "^1.2.4",
|
||||
"xmldom": "^0.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "^31.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@blockly/field-multilineinput": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@blockly/field-multilineinput/-/field-multilineinput-5.0.5.tgz",
|
||||
"integrity": "sha512-fCh+fkEeNCUwPyO6O45rH68e27RjMFWAvfUu/fYybGSIvt92uZfhZqq0veLMqAhwfYR7qQ7HIhUqvHQzAe4t6g==",
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"blockly": "^11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@blockly/theme-dark": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@blockly/theme-dark/-/theme-dark-7.0.3.tgz",
|
||||
"integrity": "sha512-lRV9V5vjijbJAlUdZqtEhUt81OjHjZK8vagxir1cUqTrZ/+MNS2m7wkhIVPba4RWInJ1LY/nHEoQn6demZqRRQ==",
|
||||
"engines": {
|
||||
"node": ">=8.17.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"blockly": "^11.0.0"
|
||||
"node_modules/@electron-fonts/noto-sans": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-fonts/noto-sans/-/noto-sans-1.2.0.tgz",
|
||||
"integrity": "sha512-czys6R1EUpuc7sbK5h5SbVRE4HScbrnx4dlOrli7AyCWomSOYnAW+5nJevibZnTseFFe8MCdORaZoCe+LXe/1Q==",
|
||||
"dependencies": {
|
||||
"electron-css-injector": "1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/get": {
|
||||
@ -153,14 +137,6 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@xmldom/xmldom": {
|
||||
"version": "0.7.13",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz",
|
||||
"integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
|
||||
@ -172,11 +148,6 @@
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/asap": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
@ -397,15 +368,6 @@
|
||||
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/dezalgo": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
|
||||
"integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
|
||||
"dependencies": {
|
||||
"asap": "^2.0.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/electron": {
|
||||
"version": "31.1.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-31.1.0.tgz",
|
||||
@ -423,6 +385,11 @@
|
||||
"node": ">= 12.20.55"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-css-injector": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/electron-css-injector/-/electron-css-injector-1.3.0.tgz",
|
||||
"integrity": "sha512-xRpwgP2fYSkB21vtL6jC77p4Gn/bc6PH2M6kOe5tOJkUsznqk3kpDe/UHpuvehHH+MMn8Mf+g24PXEADWhSvIA=="
|
||||
},
|
||||
"node_modules/electron-prompt": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/electron-prompt/-/electron-prompt-1.7.0.tgz",
|
||||
@ -534,19 +501,6 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/formidable": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz",
|
||||
"integrity": "sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==",
|
||||
"dependencies": {
|
||||
"dezalgo": "^1.0.4",
|
||||
"hexoid": "^1.0.0",
|
||||
"once": "^1.4.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://ko-fi.com/tunnckoCore/commissions"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
@ -736,14 +690,6 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/hexoid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
|
||||
"integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/html-encoding-sniffer": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
|
||||
@ -898,16 +844,6 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/mergexml": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/mergexml/-/mergexml-1.2.4.tgz",
|
||||
"integrity": "sha512-yiOlDqcVCz7AG1eSboonc18FTlfqDEKYfGoAV3Lul98u6YRV/s0kjtf4bjk47t0hLTFJR0BSYMd6BpmX3xDjNQ==",
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.7.0",
|
||||
"formidable": "^3.5.1",
|
||||
"xpath": "0.0.27"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
@ -1316,14 +1252,6 @@
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xpath": {
|
||||
"version": "0.0.27",
|
||||
"resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz",
|
||||
"integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==",
|
||||
"engines": {
|
||||
"node": ">=0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/yauzl": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
|
||||
@ -1335,17 +1263,13 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@blockly/field-multilineinput": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@blockly/field-multilineinput/-/field-multilineinput-5.0.5.tgz",
|
||||
"integrity": "sha512-fCh+fkEeNCUwPyO6O45rH68e27RjMFWAvfUu/fYybGSIvt92uZfhZqq0veLMqAhwfYR7qQ7HIhUqvHQzAe4t6g==",
|
||||
"requires": {}
|
||||
},
|
||||
"@blockly/theme-dark": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@blockly/theme-dark/-/theme-dark-7.0.3.tgz",
|
||||
"integrity": "sha512-lRV9V5vjijbJAlUdZqtEhUt81OjHjZK8vagxir1cUqTrZ/+MNS2m7wkhIVPba4RWInJ1LY/nHEoQn6demZqRRQ==",
|
||||
"requires": {}
|
||||
"@electron-fonts/noto-sans": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@electron-fonts/noto-sans/-/noto-sans-1.2.0.tgz",
|
||||
"integrity": "sha512-czys6R1EUpuc7sbK5h5SbVRE4HScbrnx4dlOrli7AyCWomSOYnAW+5nJevibZnTseFFe8MCdORaZoCe+LXe/1Q==",
|
||||
"requires": {
|
||||
"electron-css-injector": "1.3.0"
|
||||
}
|
||||
},
|
||||
"@electron/get": {
|
||||
"version": "2.0.3",
|
||||
@ -1436,11 +1360,6 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@xmldom/xmldom": {
|
||||
"version": "0.7.13",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz",
|
||||
"integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g=="
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
|
||||
@ -1449,11 +1368,6 @@
|
||||
"debug": "^4.3.4"
|
||||
}
|
||||
},
|
||||
"asap": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
@ -1602,15 +1516,6 @@
|
||||
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
|
||||
"optional": true
|
||||
},
|
||||
"dezalgo": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
|
||||
"integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
|
||||
"requires": {
|
||||
"asap": "^2.0.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"electron": {
|
||||
"version": "31.1.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-31.1.0.tgz",
|
||||
@ -1621,6 +1526,11 @@
|
||||
"extract-zip": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"electron-css-injector": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/electron-css-injector/-/electron-css-injector-1.3.0.tgz",
|
||||
"integrity": "sha512-xRpwgP2fYSkB21vtL6jC77p4Gn/bc6PH2M6kOe5tOJkUsznqk3kpDe/UHpuvehHH+MMn8Mf+g24PXEADWhSvIA=="
|
||||
},
|
||||
"electron-prompt": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/electron-prompt/-/electron-prompt-1.7.0.tgz",
|
||||
@ -1700,16 +1610,6 @@
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"formidable": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz",
|
||||
"integrity": "sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==",
|
||||
"requires": {
|
||||
"dezalgo": "^1.0.4",
|
||||
"hexoid": "^1.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
@ -1841,11 +1741,6 @@
|
||||
"function-bind": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"hexoid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
|
||||
"integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g=="
|
||||
},
|
||||
"html-encoding-sniffer": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
|
||||
@ -1968,16 +1863,6 @@
|
||||
"escape-string-regexp": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"mergexml": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/mergexml/-/mergexml-1.2.4.tgz",
|
||||
"integrity": "sha512-yiOlDqcVCz7AG1eSboonc18FTlfqDEKYfGoAV3Lul98u6YRV/s0kjtf4bjk47t0hLTFJR0BSYMd6BpmX3xDjNQ==",
|
||||
"requires": {
|
||||
"@xmldom/xmldom": "^0.7.0",
|
||||
"formidable": "^3.5.1",
|
||||
"xpath": "0.0.27"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
@ -2278,11 +2163,6 @@
|
||||
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz",
|
||||
"integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg=="
|
||||
},
|
||||
"xpath": {
|
||||
"version": "0.0.27",
|
||||
"resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz",
|
||||
"integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ=="
|
||||
},
|
||||
"yauzl": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"description": "ComputerCraft mod virtual lua IDE",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "electron src/.",
|
||||
"nodedev": "node src/."
|
||||
"dev": "electron .",
|
||||
"nodedev": "node ."
|
||||
},
|
||||
"author": "DPSoftware Foundation",
|
||||
"license": "GPL-3.0-or-later",
|
||||
@ -13,13 +13,10 @@
|
||||
"electron": "^31.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@blockly/field-multilineinput": "^5.0.5",
|
||||
"@blockly/theme-dark": "^7.0.3",
|
||||
"@electron/remote": "^2.1.2",
|
||||
"blockly": "^11.1.1",
|
||||
"bootstrap": "^5.3.3",
|
||||
"electron-prompt": "^1.7.0",
|
||||
"mergexml": "^1.2.4",
|
||||
"xmldom": "^0.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ const { DOMParser, XMLSerializer } = require('xmldom');
|
||||
|
||||
const peripheralsfolder = path.join(__dirname, "../blocks");
|
||||
|
||||
let registedblock = {}
|
||||
|
||||
function mergeXml(xml1, xml2) {
|
||||
const parser = new DOMParser();
|
||||
const serializer = new XMLSerializer();
|
||||
@ -20,7 +22,6 @@ function mergeXml(xml1, xml2) {
|
||||
}
|
||||
|
||||
const mergedXml = serializer.serializeToString(doc1);
|
||||
console.log(mergedXml)
|
||||
return mergedXml;
|
||||
}
|
||||
|
||||
@ -71,8 +72,48 @@ function loadperipheral(workspace, currenttoolbar, peripherals) {
|
||||
return newxml;
|
||||
}
|
||||
|
||||
function extractFolderName(path) {
|
||||
// Normalize path separators to handle both Windows and Unix-style paths
|
||||
const normalizedPath = path.replace(/[\\\/]/g, '/');
|
||||
// Split by '/' to get path segments
|
||||
const parts = normalizedPath.split('/');
|
||||
// Filter out empty parts and get the last segment
|
||||
const folderName = parts.filter(part => part.trim() !== '').pop();
|
||||
return folderName;
|
||||
}
|
||||
|
||||
function scanindex() {
|
||||
const files = fs.readdirSync(peripheralsfolder);
|
||||
|
||||
// Iterate through files and directories
|
||||
files.forEach(file => {
|
||||
const filePath = path.join(peripheralsfolder, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// If it's a directory, recursively call scanFolders
|
||||
const files = fs.readdirSync(filePath);
|
||||
files.forEach(file => {
|
||||
if (file === 'index.json') {
|
||||
const filePath2 = path.join(filePath, file);
|
||||
// If it's a file named index.json, read its contents
|
||||
const content = fs.readFileSync(filePath2, 'utf8');
|
||||
const jsonData = JSON.parse(content);
|
||||
|
||||
blockfoldername = extractFolderName(filePath);
|
||||
registedblock[blockfoldername] = {
|
||||
infomation: jsonData,
|
||||
image: null
|
||||
};
|
||||
console.log(`registered ${blockfoldername} blocks`)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
loadperipheral
|
||||
loadperipheral,
|
||||
scanindex
|
||||
}
|
73
src/frontend.js
Normal file
73
src/frontend.js
Normal file
@ -0,0 +1,73 @@
|
||||
var uploadpopup = document.getElementById('upload-popup');
|
||||
var aboutpopup = document.getElementById('about-popup');
|
||||
var librarypopup = document.getElementById('library-popup');
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var tooltips = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||||
var tooltipList = tooltips.map(function (tooltip) {
|
||||
return new bootstrap.Tooltip(tooltip);
|
||||
});
|
||||
});
|
||||
|
||||
// Event listener to close the upload-popup with fade-out effect
|
||||
document.getElementById('uploadCloseBtn').addEventListener('click', function() {
|
||||
uploadpopup.style.animation = 'fadeOut 0.3s ease'; // Apply fade-out animation
|
||||
setTimeout(function() {
|
||||
uploadpopup.style.display = 'none'; // Hide popup after animation completes
|
||||
uploadpopup.style.animation = ''; // Reset animation property
|
||||
}, 300); // Adjust to match animation duration in milliseconds
|
||||
});
|
||||
|
||||
document.getElementById('aboutCloseBtn').addEventListener('click', function() {
|
||||
aboutpopup.style.animation = 'fadeOut 0.3s ease'; // Apply fade-out animation
|
||||
setTimeout(function() {
|
||||
aboutpopup.style.display = 'none'; // Hide popup after animation completes
|
||||
aboutpopup.style.animation = ''; // Reset animation property
|
||||
}, 300); // Adjust to match animation duration in milliseconds
|
||||
});
|
||||
|
||||
document.getElementById('libraryCloseBtn').addEventListener('click', function() {
|
||||
librarypopup.style.animation = 'fadeOut 0.3s ease'; // Apply fade-out animation
|
||||
setTimeout(function() {
|
||||
librarypopup.style.display = 'none'; // Hide popup after animation completes
|
||||
librarypopup.style.animation = ''; // Reset animation property
|
||||
}, 300); // Adjust to match animation duration in milliseconds
|
||||
});
|
||||
|
||||
//--------------------------------
|
||||
|
||||
// Close the upload-popup if the user clicks outside of it
|
||||
window.addEventListener('click', function(event) {
|
||||
if (event.target == uploadpopup) {
|
||||
uploadpopup.style.animation = 'fadeOut 0.3s ease'; // Apply fade-out animation
|
||||
setTimeout(function() {
|
||||
uploadpopup.style.display = 'none'; // Hide popup after animation completes
|
||||
uploadpopup.style.animation = ''; // Reset animation property
|
||||
}, 300); // Adjust to match animation duration in milliseconds
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('click', function(event) {
|
||||
if (event.target == aboutpopup) {
|
||||
aboutpopup.style.animation = 'fadeOut 0.3s ease'; // Apply fade-out animation
|
||||
setTimeout(function() {
|
||||
aboutpopup.style.display = 'none'; // Hide popup after animation completes
|
||||
aboutpopup.style.animation = ''; // Reset animation property
|
||||
}, 300); // Adjust to match animation duration in milliseconds
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('click', function(event) {
|
||||
if (event.target == librarypopup) {
|
||||
librarypopup.style.animation = 'fadeOut 0.3s ease'; // Apply fade-out animation
|
||||
setTimeout(function() {
|
||||
librarypopup.style.display = 'none'; // Hide popup after animation completes
|
||||
librarypopup.style.animation = ''; // Reset animation property
|
||||
}, 300); // Adjust to match animation duration in milliseconds
|
||||
}
|
||||
});
|
||||
|
||||
function openlibraryselect() {
|
||||
librarypopup.style.display = 'block';
|
||||
}
|
||||
|
303
src/index.html
303
src/index.html
@ -4,28 +4,32 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>ccIDE</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;700&display=swap" rel="stylesheet">
|
||||
<script>
|
||||
const bootstrap = require('bootstrap')
|
||||
</script>
|
||||
<link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<!-- Loading screen -->
|
||||
<div id="loadingScreen">
|
||||
<p>Loading...</p>
|
||||
</div>
|
||||
|
||||
<!-- Navigation bar -->
|
||||
<nav id="navbar">
|
||||
<button class="navbar-button" title="Peripherals" style="background-color: #0087bd;">
|
||||
<svg viewBox="0 0 24 24"><path d="M15 7v4h1v2h-3V5h2l-3-4-3 4h2v8H8v-2.07c.7-.37 1.2-1.08 1.2-1.93A2.2 2.2 0 0 0 7 6.8c-1.22 0-2.2.98-2.2 2.2 0 .85.5 1.56 1.2 1.93V13a2 2 0 0 0 2 2h3v3.05c-.71.36-1.2 1.1-1.2 1.95a2.2 2.2 0 0 0 2.2 2.2 2.2 2.2 0 0 0 2.2-2.2c0-.85-.49-1.59-1.2-1.95V15h3a2 2 0 0 0 2-2v-2h1V7h-4z" /></svg>
|
||||
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Computer Types" style="background-color: #0087bd;">
|
||||
<svg viewBox="0 0 24 24"><path d="M6 4h12v1h3v2h-3v2h3v2h-3v2h3v2h-3v2h3v2h-3v1H6v-1H3v-2h3v-2H3v-2h3v-2H3V9h3V7H3V5h3V4m5 11v3h1v-3h-1m2 0v3h1v-3h-1m2 0v3h1v-3h-1z" /></svg>
|
||||
</button>
|
||||
<button class="navbar-button" title="Library and Packages" style="background-color: #0087bd;">
|
||||
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Library and Packages" style="background-color: #0087bd;" onclick="openlibraryselect()">
|
||||
<svg viewBox="0 0 24 24"><path d="M21 16.5c0 .38-.21.71-.53.88l-7.9 4.44c-.16.12-.36.18-.57.18-.21 0-.41-.06-.57-.18l-7.9-4.44A.991.991 0 0 1 3 16.5v-9c0-.38.21-.71.53-.88l7.9-4.44c.16-.12.36-.18.57-.18.21 0 .41.06.57.18l7.9 4.44c.32.17.53.5.53.88v9M12 4.15l-1.89 1.07L16 8.61l1.96-1.11L12 4.15M6.04 7.5 12 10.85l1.96-1.1-5.88-3.4L6.04 7.5M5 15.91l6 3.38v-6.71L5 9.21v6.7m14 0v-6.7l-6 3.37v6.71l6-3.38z" /></svg>
|
||||
</button>
|
||||
<button class="navbar-button" title="Disconnect Client" style="background-color: #bd0000; margin-left: auto; position: absolute; right: 65px;" onclick="clientexit()">
|
||||
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Peripherals" style="background-color: #0087bd;">
|
||||
<svg viewBox="0 0 24 24"><path d="M15 7v4h1v2h-3V5h2l-3-4-3 4h2v8H8v-2.07c.7-.37 1.2-1.08 1.2-1.93A2.2 2.2 0 0 0 7 6.8c-1.22 0-2.2.98-2.2 2.2 0 .85.5 1.56 1.2 1.93V13a2 2 0 0 0 2 2h3v3.05c-.71.36-1.2 1.1-1.2 1.95a2.2 2.2 0 0 0 2.2 2.2 2.2 2.2 0 0 0 2.2-2.2c0-.85-.49-1.59-1.2-1.95V15h3a2 2 0 0 0 2-2v-2h1V7h-4z" /></svg>
|
||||
</button>
|
||||
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Preview code" style="background-color: #0087bd; margin-left: auto; position: absolute; right: 115px;" onclick="clientexit()">
|
||||
<svg viewBox="0 0 24 24"><path d="M12 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0 8a5 5 0 0 1-5-5 5 5 0 0 1 5-5 5 5 0 0 1 5 5 5 5 0 0 1-5 5m0-12.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5z" /></svg>
|
||||
</button>
|
||||
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Disconnect Client" style="background-color: #bd0000; margin-left: auto; position: absolute; right: 65px;" onclick="clientexit()">
|
||||
<svg viewBox="0 0 24 24"><path d="M19 3H5c-1.11 0-2 .89-2 2v4h2V5h14v14H5v-4H3v4a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2m-8.92 12.58L11.5 17l5-5-5-5-1.42 1.41L12.67 11H3v2h9.67l-2.59 2.58z" /></svg>
|
||||
</button>
|
||||
<button class="navbar-button" title="Run" style="background-color: #10bd00; margin-left: auto;" onclick="gencode()">
|
||||
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Run" style="background-color: #10bd00; margin-left: auto;" onclick="gencode()">
|
||||
<svg viewBox="0 0 24 24"><path d="M8 5.14v14l11-7-11-7z" /></svg>
|
||||
</button>
|
||||
</nav>
|
||||
@ -42,7 +46,7 @@
|
||||
|
||||
<div class="popup" id="upload-popup">
|
||||
<div class="popup-content">
|
||||
<span class="close" id="uploadCloseBtn">×</span>
|
||||
<button type="button" class="btn-close float-end" aria-label="Close" id="uploadCloseBtn"></button>
|
||||
<div class="upload-progress-container" style="text-align: center;">
|
||||
<div class="progress-container">
|
||||
<div class="progress" id="progress"></div>
|
||||
@ -64,242 +68,53 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#loadingScreen {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #212121;
|
||||
color: #ffffff;
|
||||
display: flex; /* or display: block; */
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 2em;
|
||||
z-index: 9999;
|
||||
visibility: visible; /* Change visibility to hidden */
|
||||
}
|
||||
<div class="popup" id="about-popup">
|
||||
<div class="popup-content">
|
||||
<button type="button" class="btn-close float-end" aria-label="Close" id="aboutCloseBtn"></button>
|
||||
<h2>ccIDE</h2>
|
||||
<p>
|
||||
ccIDE is an integrated development environment designed for coding Lua scripts
|
||||
for ComputerCraft. It provides a user-friendly interface for creating and managing
|
||||
projects, designing custom blocks, and debugging scripts efficiently.
|
||||
</p>
|
||||
<p>
|
||||
Developed by DPSoftware Foundation, ccIDE aims to streamline the development
|
||||
process for ComputerCraft programmers, offering features like block-based coding,
|
||||
real-time collaboration, and seamless integration with ComputerCraft environments.
|
||||
</p>
|
||||
<p>
|
||||
Visit <a href="https://damp11113.xyz/dpsoftware/ccide">ccIDE Website</a> for more information and updates.
|
||||
</p>
|
||||
<div class="license">
|
||||
© 2024 DPSoftware Foundation. Licensed under GPL v3.
|
||||
</div>
|
||||
<style>
|
||||
.license {
|
||||
font-size: 14px;
|
||||
color: #888;
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
:root {
|
||||
--line-border-fill: #3498db;
|
||||
--line-border-empty: #e0e0e0;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #212121;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
#navbar {
|
||||
background-color: #2c3e50;
|
||||
color: white;
|
||||
display: flex;
|
||||
padding: 15px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.navbar-button {
|
||||
background-color: #2c3e50;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50%; /* Make the button circular */
|
||||
width: 40px; /* Adjust size as needed */
|
||||
height: 40px; /* Adjust size as needed */
|
||||
font-size: 1em;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
font-size: 1.5em; /* Adjust size as needed */
|
||||
}
|
||||
|
||||
.navbar-button:hover {
|
||||
background-color: #34495e; /* Darken color on hover */
|
||||
}
|
||||
|
||||
[data-bs-toggle="tooltip"] {
|
||||
position: relative; /* Ensure tooltips are positioned correctly */
|
||||
cursor: pointer; /* Add cursor style for tooltip interaction */
|
||||
}
|
||||
<div class="popup" id="library-popup">
|
||||
<div class="popup-content" style="max-width: 600px;">
|
||||
<button type="button" class="btn-close float-end" aria-label="Close" id="libraryCloseBtn"></button>
|
||||
<div class="library-container" id="libcontainer">
|
||||
<div class="library-item overflow-auto">
|
||||
<img src="image.jpg" class="libimage" onerror="this.onerror=null;this.src='../assets/noimagefallback.png'; this.alt='No Image Available';">
|
||||
<p>Lib 1</p>
|
||||
<i>Test</i>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-success btn-sm float-end">Import</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
#blocklyContainer {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: calc(100vh - 10vh); /* Adjust height to accommodate navbar and status bar */
|
||||
visibility: hidden; /* Initially hide the Blockly container */
|
||||
}
|
||||
|
||||
#blocklyDiv {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
#statusBar {
|
||||
height: 3vh; /* Set the height of the status bar */
|
||||
background-color: #333;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#statusMessage {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Styles for the upload-popup container */
|
||||
.popup {
|
||||
display: none; /* Hide initially */
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent background */
|
||||
z-index: 999; /* Ensure it overlays other content */
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* Styles for the upload-popup content */
|
||||
.popup-content {
|
||||
background-color: #fefefe;
|
||||
margin: 15% auto; /* Center the upload-popup vertically and horizontally */
|
||||
padding: 20px;
|
||||
border: 1px solid #888;
|
||||
width: 80%; /* Adjust width as needed */
|
||||
max-width: 600px; /* Max width for larger screens */
|
||||
animation: fadeIn 0.3s ease; /* Fade-in animation */
|
||||
}
|
||||
|
||||
/* Close button */
|
||||
.close {
|
||||
float: right;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.close:hover,
|
||||
.close:focus {
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Fade-in animation */
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
/* Fade-out animation */
|
||||
@keyframes fadeOut {
|
||||
from { opacity: 1; }
|
||||
to { opacity: 0; }
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
margin-bottom: 30px;
|
||||
max-width: 100%;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.progress-container::before {
|
||||
content: "";
|
||||
background-color: var(--line-border-empty);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translateY(-50%);
|
||||
height: 4px;
|
||||
width: 100%;
|
||||
z-index: 99; /* Change z-index to 1 or higher */
|
||||
}
|
||||
|
||||
.progress {
|
||||
background-color: var(--line-border-fill);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translateY(-50%);
|
||||
height: 4px;
|
||||
width: 0%;
|
||||
z-index: 101;
|
||||
transition: 0.4s ease;
|
||||
}
|
||||
|
||||
.progress.error {
|
||||
background-color: red; /* Set to red color for error state */
|
||||
}
|
||||
|
||||
|
||||
.circle {
|
||||
background-color: #fff;
|
||||
color: #999;
|
||||
border-radius: 50%;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 3px solid var(--line-border-empty);
|
||||
transition: 0.4s ease;
|
||||
z-index: 101;
|
||||
}
|
||||
|
||||
.circle.active {
|
||||
border-color: var(--line-border-fill);
|
||||
}
|
||||
|
||||
.circle.error {
|
||||
border-color: red; /* Optionally, change border color to red */
|
||||
color: white; /* Optionally, adjust text color for visibility */
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
var uploadpopup = document.getElementById('upload-popup');
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var tooltips = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||||
var tooltipList = tooltips.map(function (tooltip) {
|
||||
return new bootstrap.Tooltip(tooltip);
|
||||
});
|
||||
});
|
||||
|
||||
// Event listener to close the upload-popup with fade-out effect
|
||||
document.getElementById('uploadCloseBtn').addEventListener('click', function() {
|
||||
uploadpopup.style.animation = 'fadeOut 0.3s ease'; // Apply fade-out animation
|
||||
setTimeout(function() {
|
||||
uploadpopup.style.display = 'none'; // Hide popup after animation completes
|
||||
uploadpopup.style.animation = ''; // Reset animation property
|
||||
}, 300); // Adjust to match animation duration in milliseconds
|
||||
});
|
||||
|
||||
// Close the upload-popup if the user clicks outside of it
|
||||
window.addEventListener('click', function(event) {
|
||||
if (event.target == uploadpopup) {
|
||||
uploadpopup.style.animation = 'fadeOut 0.3s ease'; // Apply fade-out animation
|
||||
setTimeout(function() {
|
||||
uploadpopup.style.display = 'none'; // Hide popup after animation completes
|
||||
uploadpopup.style.animation = ''; // Reset animation property
|
||||
}, 300); // Adjust to match animation duration in milliseconds
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
<script src="frontend.js"></script>
|
||||
<script src="virtualcode.js"></script>
|
||||
<script src="codegen.js"></script>
|
||||
</body>
|
||||
|
@ -1,4 +1,13 @@
|
||||
{
|
||||
"sys_start": {
|
||||
"message0": "When Code Start",
|
||||
"message1": "do %1",
|
||||
"args1": [
|
||||
{"type": "input_statement", "name": "DO"}
|
||||
],
|
||||
"colour": 45,
|
||||
"tooltip": "Not require but make your code easy to read."
|
||||
},
|
||||
"sys_sleep": {
|
||||
"message0": "Sleep For %1 Second",
|
||||
"args0": [
|
||||
|
@ -9,6 +9,20 @@ if (!luaGenerator.forBlock) {
|
||||
luaGenerator.forBlock['sys_sleep'] = function(block, generator) {
|
||||
var sleepfor = generator.valueToCode(block, 'SLEEPSEC', generator.ORDER_OVERRIDES);
|
||||
|
||||
var code = `sleep(${sleepfor})`;
|
||||
var code = `sleep(${sleepfor})\n`;
|
||||
return code;
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sys_start'] = function(block, generator) {
|
||||
var docode = generator.statementToCode(block, 'DO');
|
||||
|
||||
var code =
|
||||
`
|
||||
function main()
|
||||
${docode}
|
||||
end
|
||||
|
||||
main()
|
||||
`
|
||||
return code;
|
||||
};
|
72
src/splash.html
Normal file
72
src/splash.html
Normal file
@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Splash Screen</title>
|
||||
<style>
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background-color: #2c3e50;
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
position: relative;
|
||||
}
|
||||
#splash-content {
|
||||
text-align: center;
|
||||
}
|
||||
#splash-content img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); /* Added drop shadow */
|
||||
}
|
||||
.progress-bar {
|
||||
height: 4px;
|
||||
background-color: rgba(5, 114, 206, 0.2);
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.progress-bar-value {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgb(5, 114, 206);
|
||||
animation: indeterminateAnimation 1s infinite linear;
|
||||
transform-origin: 0% 50%;
|
||||
}
|
||||
@keyframes indeterminateAnimation {
|
||||
0% {
|
||||
transform: translateX(0) scaleX(0);
|
||||
}
|
||||
40% {
|
||||
transform: translateX(0) scaleX(0.4);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(100%) scaleX(0.5);
|
||||
}
|
||||
}
|
||||
#copyright {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
font-size: 12px;
|
||||
color: #bdc3c7;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="splash-content">
|
||||
<img src="../assets/ccIDEIcon.ico" alt="ccIDE Icon">
|
||||
<h1>Loading ccIDE...</h1>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-bar-value"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="copyright">
|
||||
© 2024 DPSoftware Foundation. Licensed under GPL v3.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
190
src/styles.css
Normal file
190
src/styles.css
Normal file
@ -0,0 +1,190 @@
|
||||
:root {
|
||||
--line-border-fill: #3498db;
|
||||
--line-border-empty: #e0e0e0;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #212121;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
font-family: 'Noto Sans', sans-serif;
|
||||
overflow: hidden; /* Hide scrollbars */
|
||||
}
|
||||
|
||||
#navbar {
|
||||
background-color: #2c3e50;
|
||||
color: white;
|
||||
display: flex;
|
||||
padding: 15px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.navbar-button {
|
||||
background-color: #2c3e50;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50%; /* Make the button circular */
|
||||
width: 40px; /* Adjust size as needed */
|
||||
height: 40px; /* Adjust size as needed */
|
||||
font-size: 1em;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: background-color 0.3s;
|
||||
font-size: 1.5em; /* Adjust size as needed */
|
||||
}
|
||||
|
||||
.navbar-button:hover {
|
||||
background-color: #0066cc; /* Darken color on hover */
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
#blocklyContainer {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: calc(100vh - 10vh); /* Adjust height to accommodate navbar and status bar */
|
||||
}
|
||||
|
||||
#blocklyDiv {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
#statusBar {
|
||||
height: 3vh; /* Set the height of the status bar */
|
||||
background-color: #333;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#statusMessage {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Styles for the upload-popup container */
|
||||
.popup {
|
||||
display: none; /* Hide initially */
|
||||
position: fixed;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent background */
|
||||
z-index: 999; /* Ensure it overlays other content */
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* Styles for the upload-popup content */
|
||||
.popup-content {
|
||||
background-color: #fefefe;
|
||||
margin: 15% auto; /* Center the upload-popup vertically and horizontally */
|
||||
padding: 20px;
|
||||
border: 1px solid #888;
|
||||
width: 80%; /* Adjust width as needed */
|
||||
max-width: 600px; /* Max width for larger screens */
|
||||
animation: fadeIn 0.3s ease; /* Fade-in animation */
|
||||
}
|
||||
|
||||
|
||||
/* Fade-in animation */
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
/* Fade-out animation */
|
||||
@keyframes fadeOut {
|
||||
from { opacity: 1; }
|
||||
to { opacity: 0; }
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
margin-bottom: 30px;
|
||||
max-width: 100%;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.progress-container::before {
|
||||
content: "";
|
||||
background-color: var(--line-border-empty);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translateY(-50%);
|
||||
height: 4px;
|
||||
width: 100%;
|
||||
z-index: 99; /* Change z-index to 1 or higher */
|
||||
}
|
||||
|
||||
.progress {
|
||||
background-color: var(--line-border-fill);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translateY(-50%);
|
||||
height: 4px;
|
||||
width: 0%;
|
||||
z-index: 101;
|
||||
transition: 0.4s ease;
|
||||
}
|
||||
|
||||
.progress.error {
|
||||
background-color: red; /* Set to red color for error state */
|
||||
}
|
||||
|
||||
|
||||
.circle {
|
||||
background-color: #fff;
|
||||
color: #999;
|
||||
border-radius: 50%;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 3px solid var(--line-border-empty);
|
||||
transition: 0.4s ease;
|
||||
z-index: 101;
|
||||
}
|
||||
|
||||
.circle.active {
|
||||
border-color: var(--line-border-fill);
|
||||
}
|
||||
|
||||
.circle.error {
|
||||
border-color: red; /* Optionally, change border color to red */
|
||||
color: white; /* Optionally, adjust text color for visibility */
|
||||
}
|
||||
|
||||
.libimage {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
|
||||
}
|
||||
|
||||
.library-item {
|
||||
margin: 0 auto;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.library-item:hover {
|
||||
background-color: #cacaca;
|
||||
}
|
||||
|
||||
.library-container {
|
||||
border: 1px solid #000000;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<xml id="toolbox" style="display: none;">
|
||||
<category name="Control">
|
||||
<category name="Control" colour="38">
|
||||
<block type="sys_sleep">
|
||||
<value name="SLEEPSEC">
|
||||
<shadow type="math_number">
|
||||
@ -44,9 +44,11 @@
|
||||
</block>
|
||||
<block type="controls_forEach"></block>
|
||||
<block type="controls_flow_statements"></block>
|
||||
|
||||
</category>
|
||||
<category name="Math">
|
||||
<category name="Events" colour="45">
|
||||
<block type="sys_start"></block>
|
||||
</category>
|
||||
<category name="Math" colour="230">
|
||||
<block type="math_number" gap="32">
|
||||
<field name="NUM">123</field>
|
||||
</block>
|
||||
@ -147,7 +149,7 @@
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
<category name="Text">
|
||||
<category name="Text" colour="160">
|
||||
<block type="text"></block>
|
||||
<block type="text_join"></block>
|
||||
<block type="text_append">
|
||||
@ -249,7 +251,7 @@
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
<category name="Table">
|
||||
<category name="Table" colour="260">
|
||||
<block type="lists_create_with">
|
||||
<mutation items="0"></mutation>
|
||||
</block>
|
||||
@ -302,8 +304,9 @@
|
||||
<block type="lists_reverse"></block>
|
||||
</category>
|
||||
<sep></sep>
|
||||
<category name="Variables" custom="VARIABLE">
|
||||
<category name="Variables" custom="VARIABLE" colour="330">
|
||||
</category>
|
||||
<category name="Functions" custom="PROCEDURE" colour="290">
|
||||
</category>
|
||||
<category name="Functions" custom="PROCEDURE"></category>
|
||||
<sep></sep>
|
||||
</xml>
|
@ -1,4 +1,3 @@
|
||||
document.getElementById('statusMessage').textContent = "loading";
|
||||
// override prompt command
|
||||
window.prompt = function(promptText, defaultValue) {
|
||||
return ipc.sendSync("prompt", promptText, defaultValue);
|
||||
@ -7,12 +6,12 @@ window.prompt = function(promptText, defaultValue) {
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { ipcRenderer } = require("electron");
|
||||
const { loadperipheral } = require("./blocksmanager");
|
||||
const { loadperipheral, scanindex } = require("./blocksmanager");
|
||||
const Blockly = require('blockly');
|
||||
const { DarkTheme } = require('@blockly/theme-dark')
|
||||
const ipc = ipcRenderer;
|
||||
|
||||
let isprojectsaved = false;
|
||||
let isprojectopened = false;
|
||||
let usedlibinproject = []
|
||||
|
||||
Blockly.utils.colour.setHsvSaturation(0.9)
|
||||
@ -32,10 +31,8 @@ for (const blockId in blocksJson) {
|
||||
}
|
||||
require("./module_generator")
|
||||
|
||||
|
||||
var workspace = Blockly.inject('blocklyDiv', {
|
||||
toolbox: originaltoolbar,
|
||||
theme: DarkTheme,
|
||||
trashcan: true,
|
||||
grid: {
|
||||
spacing: 20,
|
||||
@ -45,11 +42,17 @@ var workspace = Blockly.inject('blocklyDiv', {
|
||||
}
|
||||
});
|
||||
|
||||
originaltoolbar = loadperipheral(workspace, originaltoolbar, "test");
|
||||
originaltoolbar = loadperipheral(workspace, originaltoolbar, "IDE");
|
||||
try {
|
||||
scanindex();
|
||||
|
||||
originaltoolbar = loadperipheral(workspace, originaltoolbar, "Template");
|
||||
originaltoolbar = loadperipheral(workspace, originaltoolbar, "IDE");
|
||||
} catch (e) {
|
||||
ipc.send("erroronstart", `Error on loading block: ${e}`)
|
||||
}
|
||||
workspace.getToolbox().getFlyout().autoClose = false;
|
||||
|
||||
|
||||
// Save workspace
|
||||
ipc.on('save-workspace-request', (event) => {
|
||||
const state = Blockly.serialization.workspaces.save(workspace);
|
||||
@ -81,11 +84,16 @@ workspace.addChangeListener(function(event) {
|
||||
if (isprojectsaved) {
|
||||
isprojectsaved = false
|
||||
ipc.send("workspace-notsave")
|
||||
};
|
||||
} else if (!isprojectopened) {
|
||||
ipc.send("workspace-unsave")
|
||||
}
|
||||
});
|
||||
|
||||
ipc.on('workspace-saved', (event, success) => {
|
||||
isprojectsaved = success
|
||||
if (!isprojectopened) {
|
||||
isprojectopened = true;
|
||||
}
|
||||
});
|
||||
|
||||
ipc.on('request-undo-redo', (event, redo) => {
|
||||
@ -93,8 +101,10 @@ ipc.on('request-undo-redo', (event, redo) => {
|
||||
workspace.undo(redo)
|
||||
});
|
||||
|
||||
// Ensure Blockly container is shown after the workspace is injected
|
||||
document.getElementById('loadingScreen').style.visibility = 'hidden';
|
||||
document.getElementById('blocklyContainer').style.visibility = 'visible';
|
||||
document.getElementById('statusMessage').textContent = "ready";
|
||||
ipc.on("open-about", () => {
|
||||
document.getElementById('about-popup').style.display = 'block';
|
||||
})
|
||||
|
||||
// Ensure Blockly container is shown after the workspace is injected
|
||||
document.getElementById('statusMessage').textContent = "ready";
|
||||
ipc.send("ready")
|
Loading…
x
Reference in New Issue
Block a user