Files
MycLib/Blockly/blockly_delphi_test.html
T
Michael Schimmel 7516bd3d9d Blockly test
2025-06-10 22:31:16 +02:00

163 lines
7.6 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Blockly zu Delphi Unit - Final</title>
<style>
body { font-family: sans-serif; }
#container { display: flex; }
#outputArea { margin-left: 20px; }
#codeOutput { width: 400px; height: 580px; font-family: 'Courier New', Courier, monospace; font-size: 14px; white-space: pre-wrap; border: 1px solid #ccc; }
#blocklyDiv { height: 600px; width: 800px; }
.button-bar { margin-bottom: 10px; }
</style>
</head>
<body>
<h1>Mein Delphi-Unit-Generator</h1>
<p>Bauen Sie links Ihre Blöcke. Rechts erscheint die kompilierbare Delphi-Unit.</p>
<div class="button-bar">
<button onclick="saveWorkspace()">Speichern</button>
<button onclick="loadWorkspace()">Letzten Stand laden</button>
<button onclick="generateAndPostCode()">Code generieren und posten</button>
</div>
<div id="container">
<div id="blocklyDiv"></div>
<div id="outputArea">
<h2>Erzeugter Delphi-Code:</h2>
<textarea id="codeOutput" readonly></textarea>
</div>
</div>
<script src="https://unpkg.com/blockly/blockly_compressed.js"></script>
<script src="https://unpkg.com/blockly/blocks_compressed.js"></script>
<script src="https://unpkg.com/blockly/msg/de.js"></script>
<script>
window.onload = function() {
let workspace;
// === DER DELPHI-GENERATOR ===
Blockly.Delphi = new Blockly.Generator('Delphi');
Blockly.Delphi.ORDER_ATOMIC = 0;
Blockly.Delphi.ORDER_NONE = 99;
Blockly.Delphi.workspaceToCode = function(workspace) {
const allVariables = workspace.getAllVariables();
let varDeclarations = '';
if (allVariables.length > 0) {
const varNames = allVariables.map(v => v.name).join(', ');
varDeclarations = ` var\n ${varNames}: Integer;\n`;
}
varDeclarations += ' i: Integer; // Schleifenzähler\n';
const topBlocks = workspace.getTopBlocks(true);
const code = topBlocks.map(block => Blockly.Delphi.blockToCode(block)).join(';\n');
let unitCode = 'unit MeinProgramm;\n\n';
unitCode += 'interface\n\n';
unitCode += 'uses\n System.SysUtils;\n\n';
unitCode += 'procedure StarteLogik;\n\n';
unitCode += 'implementation\n\n';
unitCode += 'procedure StarteLogik;\n';
if (varDeclarations) unitCode += varDeclarations;
unitCode += 'begin\n';
unitCode += ' ' + code.split('\n').join('\n ');
unitCode += '\nend;\n\n';
unitCode += 'end.';
return unitCode;
};
Blockly.Delphi.scrub_ = function(block, code, opt_thisOnly) {
const nextBlock = block.nextConnection && block.nextConnection.targetBlock();
const nextCode = opt_thisOnly ? '' : Blockly.Delphi.blockToCode(nextBlock);
return code + (nextBlock ? ';\n' : '') + nextCode;
};
Blockly.Delphi.forBlock['controls_if'] = function(block) {
let conditionCode = Blockly.Delphi.valueToCode(block, 'IF0', Blockly.Delphi.ORDER_NONE) || 'False';
let branchCode = Blockly.Delphi.statementToCode(block, 'DO0') || '';
let code = `if (${conditionCode}) then\nbegin\n${Blockly.Delphi.prefixLines(branchCode, ' ')}\nend`;
return code;
};
Blockly.Delphi.forBlock['logic_compare'] = function(block) {
const OPERATORS = {'EQ': '=', 'NEQ': '<>', 'LT': '<', 'LTE': '<=', 'GT': '>', 'GTE': '>='};
const operator = OPERATORS[block.getFieldValue('OP')];
const value_a = Blockly.Delphi.valueToCode(block, 'A', Blockly.Delphi.ORDER_ATOMIC) || '0';
const value_b = Blockly.Delphi.valueToCode(block, 'B', Blockly.Delphi.ORDER_ATOMIC) || '0';
return [`${value_a} ${operator} ${value_b}`, Blockly.Delphi.ORDER_ATOMIC];
};
Blockly.Delphi.forBlock['controls_repeat_ext'] = function(block) {
const repeats = Blockly.Delphi.valueToCode(block, 'TIMES', Blockly.Delphi.ORDER_ATOMIC) || '0';
const branch = Blockly.Delphi.statementToCode(block, 'DO') || '';
let code = `for i := 1 to ${repeats} do\nbegin\n${Blockly.Delphi.prefixLines(branch, ' ')}\nend`;
return code;
};
Blockly.Delphi.forBlock['math_number'] = function(block) { return [String(block.getFieldValue('NUM')), Blockly.Delphi.ORDER_ATOMIC]; };
Blockly.Delphi.forBlock['variables_get'] = function(block) { const varName = block.workspace.getVariableById(block.getFieldValue('VAR')).name; return [varName, Blockly.Delphi.ORDER_ATOMIC]; };
Blockly.Delphi.forBlock['variables_set'] = function(block) { const varName = block.workspace.getVariableById(block.getFieldValue('VAR')).name; const value = Blockly.Delphi.valueToCode(block, 'VALUE', Blockly.Delphi.ORDER_ATOMIC) || '0'; return `${varName} := ${value}`;};
Blockly.Delphi.forBlock['math_change'] = function(block) { const varName = block.workspace.getVariableById(block.getFieldValue('VAR')).name; const delta = Blockly.Delphi.valueToCode(block, 'DELTA', Blockly.Delphi.ORDER_ATOMIC) || '0'; if (delta == '1') return `Inc(${varName})`; if (delta == '-1') return `Dec(${varName})`; return `${varName} := ${varName} + ${delta}`; };
Blockly.Delphi.forBlock['text_print'] = function(block) { const value = Blockly.Delphi.valueToCode(block, 'TEXT', Blockly.Delphi.ORDER_ATOMIC) || `''`; return `WriteLn(${value})`; };
Blockly.Delphi.forBlock['text'] = function(block) { const text = block.getFieldValue('TEXT').replace(/'/g, "''"); return [`'${text}'`, Blockly.Delphi.ORDER_ATOMIC]; };
// === INITIALISIERUNG VON BLOCKLY (JETZT KORREKT) ===
// 1. Definition der Werkzeugkiste (Toolbox)
const toolboxXml = `
<xml>
<category name="Logik" colour="%{BKY_LOGIC_HUE}">
<block type="controls_if"></block>
<block type="logic_compare"></block>
</category>
<category name="Schleifen" colour="%{BKY_LOOPS_HUE}">
<block type="controls_repeat_ext">
<value name="TIMES"><shadow type="math_number"><field name="NUM">10</field></shadow></value>
</block>
</category>
<category name="Text" colour="%{BKY_TEXTS_HUE}">
<block type="text_print"></block>
<block type="text"></block>
</category>
<category name="Mathematik" colour="%{BKY_MATH_HUE}">
<block type="math_number"></block>
<block type="math_change">
<value name="DELTA"><shadow type="math_number"><field name="NUM">1</field></shadow></value>
</block>
</category>
<category name="Variablen" colour="%{BKY_VARIABLES_HUE}" custom="VARIABLE"></category>
</xml>`;
// 2. Blockly in den Div-Container "injizieren"
workspace = Blockly.inject('blocklyDiv', {
toolbox: toolboxXml
});
function generateAndPostCode() {
const code = Blockly.Delphi.workspaceToCode(workspace);
// Diese spezielle Funktion sendet eine Nachricht an den Delphi-Host
window.chrome.webview.postMessage(code);
}
window.generateAndPostCode = function() { generateAndPostCode(); }
// === Funktionen für Speichern und Laden (unverändert) ===
window.saveWorkspace = function() { const state = Blockly.serialization.workspaces.save(workspace); localStorage.setItem('blocklyWorkspace', JSON.stringify(state)); alert('Arbeitsbereich gespeichert!'); }
window.loadWorkspace = function() { const stateString = localStorage.getItem('blocklyWorkspace'); if (!stateString) { return; } const state = JSON.parse(stateString); Blockly.serialization.workspaces.load(state, workspace); }
function updateCode(event) { if (event.type == Blockly.Events.UI) return; const code = Blockly.Delphi.workspaceToCode(workspace); document.getElementById('codeOutput').value = code; }
workspace.addChangeListener(updateCode);
loadWorkspace();
};
</script>
</body>
</html>