mirror of
https://github.com/damp11113-software/ccIDE.git
synced 2025-04-27 22:48:13 +00:00
update 1.0.2
add save load new and make code more readable not complex
This commit is contained in:
parent
b5cf9c9b64
commit
aa6d2199c4
4
.gitignore
vendored
4
.gitignore
vendored
@ -1 +1,3 @@
|
||||
node_modules/
|
||||
node_modules/
|
||||
.mcattributes
|
||||
package-lock.json
|
||||
|
14
blocks/test/index.json
Normal file
14
blocks/test/index.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "Test Peripheral",
|
||||
"author": "DPSoftware Foundation",
|
||||
"description": "Test Peripheral",
|
||||
"version": "1.0.0",
|
||||
"category": "Blockly Extensions",
|
||||
"keyword": "test",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"peripherals": false,
|
||||
"library": false,
|
||||
"turtle": false,
|
||||
"system": true,
|
||||
"require_network": false
|
||||
}
|
BIN
ccIDE Defines.xlsx
Normal file
BIN
ccIDE Defines.xlsx
Normal file
Binary file not shown.
Binary file not shown.
221
package-lock.json
generated
221
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ccide",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.2",
|
||||
"description": "ComputerCraft mod virtual lua IDE",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@ -13,6 +13,7 @@
|
||||
"electron": "^31.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@electron/remote": "^2.1.2",
|
||||
"blockly": "^11.1.1",
|
||||
"bootstrap": "^5.3.3",
|
||||
"electron-prompt": "^1.7.0"
|
||||
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"name": "Test Peripheral",
|
||||
"author": "DPSoftware Foundation",
|
||||
"description": "Test Peripheral",
|
||||
"version": "1.0.0",
|
||||
"category": "Blockly Extensions",
|
||||
"license": "GPL-3.0-or-later"
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const peripheralsfolder = path.join(__dirname, "../peripherals");
|
||||
const peripheralsfolder = path.join(__dirname, "../blocks");
|
||||
|
||||
function mergeXml(originalXml, appendXml) {
|
||||
// Remove <xml id="toolbox" style="display: none;"> and </xml> from appendXml
|
||||
@ -22,7 +22,7 @@ function mergeXml(originalXml, appendXml) {
|
||||
return modifiedXml;
|
||||
}
|
||||
|
||||
function loadperipheral(workspace, originaltoolbar, peripherals) {
|
||||
function loadperipheral(workspace, currenttoolbar, peripherals) {
|
||||
const filePath = path.join(peripheralsfolder, peripherals);
|
||||
const jsonfilePath = path.join(filePath, "block_design.json");
|
||||
const xmlfilePath = path.join(filePath, "toolbox.xml");
|
||||
@ -53,24 +53,24 @@ function loadperipheral(workspace, originaltoolbar, peripherals) {
|
||||
});
|
||||
|
||||
// Load and merge new toolbox XML
|
||||
try {
|
||||
const toolbar = fs.readFileSync(xmlfilePath, 'utf8');
|
||||
const newxml = mergeXml(originaltoolbar, toolbar);
|
||||
|
||||
workspace.updateToolbox(newxml);
|
||||
const toolbar = fs.readFileSync(xmlfilePath, 'utf8');
|
||||
const newxml = mergeXml(currenttoolbar, toolbar);
|
||||
|
||||
workspace.updateToolbox(newxml);
|
||||
|
||||
document.getElementById('statusMessage').textContent = `Loaded ${peripherals}`;
|
||||
|
||||
document.getElementById('statusMessage').textContent = `Loaded ${peripherals}`;
|
||||
} catch (error) {
|
||||
console.error('Error loading or merging XML:', error);
|
||||
document.getElementById('statusMessage').textContent = `Can't Load ${peripherals}`;
|
||||
}
|
||||
try {
|
||||
require(generatorfilePath); // This will execute generator.js if it's a Node.js module
|
||||
} catch (error) {
|
||||
console.error('Error loading generator.js:', error);
|
||||
}
|
||||
|
||||
return newxml;
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
loadperipheral
|
||||
}
|
75
src/codegen.js
Normal file
75
src/codegen.js
Normal file
@ -0,0 +1,75 @@
|
||||
function delay(time) {
|
||||
return new Promise(resolve => setTimeout(resolve, time));
|
||||
}
|
||||
|
||||
const { luaGenerator } = require('blockly/lua'); // Use require syntax for Blockly module
|
||||
|
||||
const progress = document.getElementById("progress");
|
||||
const circles = document.querySelectorAll(".circle");
|
||||
let upcurrentActive = 1;
|
||||
let uploadError = false; // Flag to track if there's an error
|
||||
|
||||
const uploadUpdateProgress = () => {
|
||||
circles.forEach((circle, index) => {
|
||||
if (index < upcurrentActive) {
|
||||
circle.classList.add("active");
|
||||
if (index === upcurrentActive - 1 && uploadError) {
|
||||
circle.classList.add("error");
|
||||
} else {
|
||||
circle.classList.remove("error");
|
||||
}
|
||||
} else {
|
||||
circle.classList.remove("active");
|
||||
circle.classList.remove("error"); // Ensure no error class on inactive circles
|
||||
}
|
||||
});
|
||||
|
||||
if (uploadError) {
|
||||
progress.classList.add("error");
|
||||
} else {
|
||||
const actives = document.querySelectorAll(".active");
|
||||
progress.style.width = ((actives.length - 1) / (circles.length - 1)) * 100 + "%";
|
||||
progress.classList.remove("error");
|
||||
}
|
||||
};
|
||||
|
||||
async function gencode() {
|
||||
document.getElementById('upload-popup').style.display = 'block';
|
||||
upcurrentActive = 1;
|
||||
uploadError = false;
|
||||
uploadUpdateProgress();
|
||||
// compile/convert code
|
||||
|
||||
upcurrentActive++;
|
||||
uploadUpdateProgress();
|
||||
document.getElementById('upload-status').textContent = "Generating code";
|
||||
try {
|
||||
let code = luaGenerator.workspaceToCode(workspace);
|
||||
console.log(code);
|
||||
} catch (e) {
|
||||
uploadError = true;
|
||||
uploadUpdateProgress();
|
||||
document.getElementById('upload-status').textContent = e;
|
||||
return
|
||||
}
|
||||
|
||||
// upload to computercraft with remote
|
||||
document.getElementById('upload-status').textContent = "Uploading code to machine";
|
||||
upcurrentActive++;
|
||||
uploadUpdateProgress();
|
||||
await delay(1000)
|
||||
|
||||
// execute with remote
|
||||
document.getElementById('upload-status').textContent = "Executing code";
|
||||
upcurrentActive++;
|
||||
uploadUpdateProgress();
|
||||
await delay(1000)
|
||||
|
||||
// done!
|
||||
document.getElementById('upload-status').textContent = "Done!";
|
||||
document.getElementById('upload-popup').style.animation = 'fadeOut 0.3s ease'; // Apply fade-out animation
|
||||
setTimeout(function() {
|
||||
document.getElementById('upload-popup').style.display = 'none'; // Hide popup after animation completes
|
||||
document.getElementById('upload-popup').style.animation = ''; // Reset animation property
|
||||
}, 300); // Adjust to match animation duration in milliseconds
|
||||
}
|
216
src/index.html
216
src/index.html
@ -9,22 +9,24 @@
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Navigation bar -->
|
||||
<!-- 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>
|
||||
<button class="navbar-button" title="Library and Packages" style="background-color: #0087bd;">
|
||||
<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="Run" style="background-color: #0087bd; margin-left: auto;" onclick="gencode()">
|
||||
<svg viewBox="0 0 24 24"><path d="M8 5.14v14l11-7-11-7z" /></svg>
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<!-- Loading screen -->
|
||||
<div id="loadingScreen">
|
||||
<p>Loading...</p>
|
||||
</div>
|
||||
|
||||
<!-- Blockly workspace container -->
|
||||
<section id="blocklyContainer">
|
||||
<div id="blocklyDiv"></div>
|
||||
@ -35,7 +37,52 @@
|
||||
<p id="statusMessage">Initializing...</p>
|
||||
</div>
|
||||
|
||||
<div class="popup" id="upload-popup">
|
||||
<div class="popup-content">
|
||||
<span class="close" id="uploadCloseBtn">×</span>
|
||||
<div class="upload-progress-container" style="text-align: center;">
|
||||
<div class="progress-container">
|
||||
<div class="progress" id="progress"></div>
|
||||
<div class="circle active">
|
||||
<svg viewBox="0 0 24 24"><path d="M8 3a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2H3v2h1a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h2v-2H8v-5a2 2 0 0 0-2-2 2 2 0 0 0 2-2V5h2V3m6 0a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h1v2h-1a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-2v-2h2v-5a2 2 0 0 1 2-2 2 2 0 0 1-2-2V5h-2V3h2z" /></svg>
|
||||
</div>
|
||||
<div class="circle">
|
||||
<svg viewBox="0 0 24 24"><path d="m5.5 4.14-1 1.72L15 12 4.5 18.14l1 1.72L19 12 5.5 4.14z" /></svg>
|
||||
</div>
|
||||
<div class="circle">
|
||||
<svg viewBox="0 0 24 24"><path d="M9 16v-6H5l7-7 7 7h-4v6H9m-4 4v-2h14v2H5z" /></svg>
|
||||
</div>
|
||||
<div class="circle">
|
||||
<svg viewBox="0 0 24 24"><path d="m20 22-3.86-1.55c.7-1.53 1.2-3.11 1.51-4.72L20 22M7.86 20.45 4 22l2.35-6.27c.31 1.61.81 3.19 1.51 4.72M12 2s5 2 5 10c0 3.1-.75 5.75-1.67 7.83A2 2 0 0 1 13.5 21h-3a2 2 0 0 1-1.83-1.17C7.76 17.75 7 15.1 7 12c0-8 5-10 5-10m0 10c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z" /></svg>
|
||||
</div>
|
||||
</div>
|
||||
<p id="upload-status"></p>
|
||||
</div>
|
||||
</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 */
|
||||
}
|
||||
|
||||
:root {
|
||||
--line-border-fill: #3498db;
|
||||
--line-border-empty: #e0e0e0;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #212121;
|
||||
margin: 0;
|
||||
@ -77,26 +124,12 @@
|
||||
cursor: pointer; /* Add cursor style for tooltip interaction */
|
||||
}
|
||||
|
||||
#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 : 1;
|
||||
}
|
||||
|
||||
|
||||
#blocklyContainer {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: calc(100vh - 10vh); /* Adjust height to accommodate navbar and status bar */
|
||||
display: none; /* Initially hide the Blockly container */
|
||||
visibility: hidden; /* Initially hide the Blockly container */
|
||||
}
|
||||
|
||||
#blocklyDiv {
|
||||
@ -105,7 +138,6 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
color: #212121;
|
||||
}
|
||||
|
||||
#statusBar {
|
||||
@ -121,17 +153,151 @@
|
||||
#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);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="virtualcode.js"></script>
|
||||
// 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="virtualcode.js"></script>
|
||||
<script src="codegen.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
223
src/index.js
223
src/index.js
@ -1,14 +1,27 @@
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
const { app, BrowserWindow, ipcMain, Menu, dialog } = require('electron')
|
||||
const fs = require('fs');
|
||||
const prompt = require('electron-prompt');
|
||||
const path = require('path');
|
||||
const ipc = ipcMain
|
||||
|
||||
let currentprojectpath = null;
|
||||
let currentprojectname = null;
|
||||
let currentprojectopen = false
|
||||
let appexiting = false
|
||||
|
||||
app.whenReady().then(() => {
|
||||
currentprojectpath = null;
|
||||
currentprojectname = null;
|
||||
currentprojectopen = false;
|
||||
appexiting = false;
|
||||
|
||||
const win = new BrowserWindow({
|
||||
width: 1300,
|
||||
height: 740,
|
||||
width: 1280,
|
||||
height: 720,
|
||||
webPreferences: {
|
||||
devTools: true,
|
||||
nodeIntegration: true,
|
||||
enableRemoteModule: true,
|
||||
contextIsolation: false,
|
||||
}
|
||||
})
|
||||
@ -16,11 +29,118 @@ app.whenReady().then(() => {
|
||||
win.loadFile('index.html')
|
||||
//win.openDevTools();
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
//app.on('activate', () => {
|
||||
// if (BrowserWindow.getAllWindows().length === 0) {
|
||||
// createWindow()
|
||||
// }
|
||||
//})
|
||||
|
||||
// Define a custom menu template
|
||||
const menuTemplate = [
|
||||
{
|
||||
label: 'File',
|
||||
submenu: [
|
||||
{
|
||||
label: 'New',
|
||||
accelerator: 'CmdOrCtrl+N',
|
||||
click: () => {
|
||||
win.reload()
|
||||
}
|
||||
},
|
||||
{
|
||||
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];
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Save',
|
||||
accelerator: 'CmdOrCtrl+S',
|
||||
click: () => {
|
||||
win.webContents.send('save-workspace-request');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Save as',
|
||||
accelerator: 'CmdOrCtrl+Shift+S',
|
||||
click: () => {
|
||||
currentprojectopen = false
|
||||
win.webContents.send('save-workspace-request');
|
||||
}
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Exit',
|
||||
accelerator: 'CmdOrCtrl+Q',
|
||||
click: () => {
|
||||
app.quit();
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Edit',
|
||||
submenu: [
|
||||
{ role: 'undo', accelerator: 'CmdOrCtrl+Z' },
|
||||
{ role: 'redo', accelerator: 'CmdOrCtrl+Y' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'cut', accelerator: 'CmdOrCtrl+X' },
|
||||
{ role: 'copy', accelerator: 'CmdOrCtrl+C' },
|
||||
{ role: 'paste', accelerator: 'CmdOrCtrl+V' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{ label: 'DevTools', accelerator: 'F12', click: () => {win.openDevTools()}},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'About',
|
||||
click: () => {
|
||||
console.log('About clicked');
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
];
|
||||
|
||||
// Set the custom menu
|
||||
const menu = Menu.buildFromTemplate(menuTemplate);
|
||||
Menu.setApplicationMenu(menu);
|
||||
|
||||
ipc.on('prompt', (event, promptText, defaultValue) => {
|
||||
try {
|
||||
@ -48,4 +168,91 @@ app.whenReady().then(() => {
|
||||
event.returnValue = null; // or handle error appropriately
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
ipc.on('save-workspace', (event, json) => {
|
||||
if (!currentprojectopen) {
|
||||
dialog.showSaveDialog(win, {
|
||||
title: 'Save Project',
|
||||
defaultPath: path.join(app.getPath('documents'), 'untitled.ccp'),
|
||||
filters: [
|
||||
{ name: 'ComputerCraft Project', extensions: ['ccp'] }
|
||||
]
|
||||
}).then(result => {
|
||||
if (!result.canceled) {
|
||||
fs.writeFile(result.filePath, JSON.stringify(json), (err) => {
|
||||
if (err) {
|
||||
console.error('Error saving project:', err);
|
||||
dialog.showErrorBox("Save Project Error", err.message)
|
||||
win.webContents.send('workspace-saved', false);
|
||||
} else {
|
||||
currentprojectpath = result.filePath
|
||||
currentprojectname = path.basename(result.filePath);
|
||||
currentprojectopen = true;
|
||||
|
||||
win.webContents.send('workspace-saved', true);
|
||||
|
||||
win.setTitle(`${currentprojectname} | ccIDE`)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
win.webContents.send('workspace-saved', false);
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('Error showing save dialog:', err);
|
||||
dialog.showErrorBox("Save Project Error", err.message)
|
||||
win.webContents.send('workspace-saved', false);
|
||||
});
|
||||
} else {
|
||||
fs.writeFile(currentprojectpath, JSON.stringify(json), (err) => {
|
||||
if (err) {
|
||||
console.error('Error saving project:', err);
|
||||
dialog.showErrorBox("Save Project Error", err.message)
|
||||
win.webContents.send('workspace-saved', false);
|
||||
} else {
|
||||
currentprojectopen = true;
|
||||
|
||||
win.webContents.send('workspace-saved', true);
|
||||
|
||||
win.setTitle(`${currentprojectname} | ccIDE`)
|
||||
|
||||
if (appexiting) {
|
||||
app.quit();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
ipc.on('workspace-notsave', (event) => {
|
||||
win.setTitle(`${currentprojectname}* | ccIDE`)
|
||||
})
|
||||
|
||||
/*
|
||||
win.on('close', function(e){
|
||||
win.show()
|
||||
});
|
||||
|
||||
app.on("before-quit", function() {
|
||||
if (currentprojectopen) {
|
||||
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) {
|
||||
win = null
|
||||
} else if (result === 0) {
|
||||
appexiting = true;
|
||||
win.webContents.send('save-workspace-request');
|
||||
|
||||
}
|
||||
} else {
|
||||
win = null
|
||||
}
|
||||
|
||||
})
|
||||
*/
|
||||
})
|
||||
|
||||
|
@ -242,7 +242,7 @@
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
<category name="Lists">
|
||||
<category name="Table">
|
||||
<block type="lists_create_with">
|
||||
<mutation items="0"></mutation>
|
||||
</block>
|
||||
|
@ -1,40 +1,24 @@
|
||||
document.getElementById('statusMessage').textContent = "loading";
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { ipcRenderer } = require("electron");
|
||||
const { loadperipheral } = require("./blocksmanager");
|
||||
const { luaGenerator } = require('blockly/lua'); // Use require syntax for Blockly module
|
||||
|
||||
const ipc = ipcRenderer;
|
||||
|
||||
// override prompt command
|
||||
window.prompt = function(promptText, defaultValue) {
|
||||
return ipc.sendSync("prompt", promptText, defaultValue);
|
||||
};
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { ipcRenderer } = require("electron");
|
||||
const { loadperipheral } = require("./blocksmanager");
|
||||
const Blockly = require('blockly');
|
||||
const ipc = ipcRenderer;
|
||||
|
||||
|
||||
let isprojectsaved = false;
|
||||
let usedlibinproject = []
|
||||
|
||||
Blockly.utils.colour.setHsvSaturation(0.9)
|
||||
|
||||
const peripheralsfolder = path.join(__dirname, "../peripherals");
|
||||
|
||||
const originaltoolbar = fs.readFileSync(path.join(__dirname, "toolbox.xml"), 'utf8');
|
||||
const sysmodulejson = fs.readFileSync(path.join(__dirname, "module_block_design.json"), 'utf8');
|
||||
|
||||
|
||||
const blocksJson = JSON.parse(sysmodulejson);
|
||||
for (const blockId in blocksJson) {
|
||||
if (blocksJson.hasOwnProperty(blockId)) {
|
||||
Blockly.Blocks[blockId] = {
|
||||
init: function() {
|
||||
this.jsonInit(blocksJson[blockId]);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
let originaltoolbar = fs.readFileSync(path.join(__dirname, "toolbox.xml"), 'utf8');
|
||||
|
||||
|
||||
var workspace = Blockly.inject('blocklyDiv', {
|
||||
toolbox: originaltoolbar,
|
||||
trashcan: true,
|
||||
@ -46,17 +30,49 @@ var workspace = Blockly.inject('blocklyDiv', {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
loadperipheral(workspace, originaltoolbar, "test");
|
||||
|
||||
document.getElementById('statusMessage').textContent = "ready";
|
||||
originaltoolbar = loadperipheral(workspace, originaltoolbar, "test");
|
||||
|
||||
workspace.getToolbox().getFlyout().autoClose = false;
|
||||
|
||||
// Ensure Blockly container is shown after the workspace is injected
|
||||
document.getElementById('loadingScreen').style.display = 'none';
|
||||
document.getElementById('blocklyContainer').style.display = 'block';
|
||||
// Save workspace
|
||||
ipc.on('save-workspace-request', (event) => {
|
||||
const state = Blockly.serialization.workspaces.save(workspace);
|
||||
const data = {
|
||||
"usedlibrary": usedlibinproject,
|
||||
"content": state
|
||||
}
|
||||
ipc.send('save-workspace', data);
|
||||
});
|
||||
|
||||
function gencode() {
|
||||
return luaGenerator.workspaceToCode(workspace);
|
||||
}
|
||||
// Load workspace
|
||||
ipc.on('load-workspace', (event, json) => {
|
||||
if (json) {
|
||||
data = JSON.parse(json)
|
||||
usedlibinproject = data.usedlibrary
|
||||
workspace.clear()
|
||||
Blockly.serialization.workspaces.load(data.content, workspace);
|
||||
isprojectsaved = true
|
||||
}
|
||||
})
|
||||
|
||||
workspace.addChangeListener(function(event) {
|
||||
if ([Blockly.Events.UI,
|
||||
Blockly.Events.VIEWPORT_CHANGE,
|
||||
Blockly.Events.TOOLBOX_ITEM_SELECT]
|
||||
.includes(event.type)) {
|
||||
return; // Don't care about UI events.
|
||||
}
|
||||
if (isprojectsaved) {
|
||||
isprojectsaved = false
|
||||
ipc.send("workspace-notsave")
|
||||
};
|
||||
});
|
||||
|
||||
ipc.on('workspace-saved', (event, success) => {
|
||||
isprojectsaved = success
|
||||
});
|
||||
|
||||
// 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";
|
Loading…
x
Reference in New Issue
Block a user