Files
t2000-steckerpruefer/pagecontent/bridge-editor.php
2026-01-02 20:52:43 +01:00

410 lines
13 KiB
PHP
Executable File

<?php
// Diese Seite ist für den Brücken-Editor
session_start();
$db = new SQLite3('../db-test/test.db');
$view = $_GET["view"];
$meta = $_GET["meta"];
$_SESSION["meta"]=$meta;
switch($view) {
case "add": // Neue Brücke anlegen
?>
<div class="content-header">Brücken-Editor - Neu anlegen</div>
<div class="plug-table">
<?php
$url = '../stecker.php?data=';
?>
<canvas id="bridge-editor-img" meta="<?php echo urlencode('[]'); ?>" style="background-image: url('<?php echo $url; ?>');" width="500" height="100"></canvas>
<script>
// Dieses Skript ist zum Großteil aus dem Internet kopiert, jedoch dann an die eigenen Bedürfnisse angepasst worden - Quelle: keine Ahnung
var canvas = document.getElementById('bridge-editor-img');
var ctx = canvas.getContext('2d');
var offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = canvas.width;
offscreenCanvas.height = canvas.height;
var offCtx = offscreenCanvas.getContext('2d');
var rects = [
// Obere Zeile
{id: 31, x: 405, y: 20}, {id: 32, x: 370, y: 20}, {id: 33, x: 335, y: 20},
{id: 34, x: 300, y: 20}, {id: 35, x: 265, y: 20}, {id: 36, x: 230, y: 20},
{id: 37, x: 195, y: 20}, {id: 38, x: 160, y: 20}, {id: 39, x: 125, y: 20},
{id: 30, x: 70, y: 20},
// Mittlere Zeile
{id: 21, x: 405, y: 44}, {id: 22, x: 370, y: 44}, {id: 23, x: 335, y: 44},
{id: 24, x: 300, y: 44}, {id: 25, x: 265, y: 44}, {id: 26, x: 220, y: 44},
{id: 27, x: 185, y: 44}, {id: 28, x: 150, y: 44}, {id: 29, x: 115, y: 44},
{id: 20, x: 70, y: 44},
// Untere Zeile
{id: 11, x: 405, y: 68}, {id: 12, x: 370, y: 68}, {id: 13, x: 335, y: 68},
{id: 14, x: 300, y: 68}, {id: 15, x: 265, y: 68}, {id: 16, x: 230, y: 68},
{id: 17, x: 195, y: 68}, {id: 18, x: 160, y: 68}, {id: 19, x: 125, y: 68},
{id: 10, x: 70, y: 68}
];
var colorID = 0;
var RECT_WIDTH = 25;
var RECT_HEIGHT = 10;
var drawing = false;
var startPoint = null;
function getCenterIfInRect(x, y) {
for (var rect of rects) {
if (
x >= rect.x &&
x <= rect.x + RECT_WIDTH &&
y >= rect.y &&
y <= rect.y + RECT_HEIGHT
) {
return {
x: rect.x + RECT_WIDTH / 2,
y: rect.y + RECT_HEIGHT / 2,
id: rect.id
};
}
}
return null;
}
canvas.addEventListener('mousedown', (e) => {
var rect = canvas.getBoundingClientRect();
var mouseX = e.clientX - rect.left;
var mouseY = e.clientY - rect.top;
var center = getCenterIfInRect(mouseX, mouseY);
if (center) {
startPoint = center;
drawing = true;
}
});
canvas.addEventListener('mousemove', (e) => {
if (!drawing || !startPoint) return;
var rect = canvas.getBoundingClientRect();
var mouseX = e.clientX - rect.left;
var mouseY = e.clientY - rect.top;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(offscreenCanvas, 0, 0);
ctx.beginPath();
ctx.moveTo(startPoint.x, startPoint.y);
ctx.lineTo(mouseX, mouseY);
ctx.strokeStyle = "red";
offCtx.lineWidth = 3;
ctx.stroke();
});
canvas.addEventListener('mouseup', (e) => {
if (!drawing || !startPoint) return;
var rect = canvas.getBoundingClientRect();
var mouseX = e.clientX - rect.left;
var mouseY = e.clientY - rect.top;
var endPoint = getCenterIfInRect(mouseX, mouseY);
drawing = false;
if (endPoint && startPoint.id !== endPoint.id) {
connectPins(startPoint.id, endPoint.id, "canvas");
ctx.clearRect(0, 0, canvas.width, canvas.height);
} else {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(offscreenCanvas, 0, 0);
}
startPoint = null;
});
</script>
<?php
echo '
</div>
<div class="pin-table">'; // Hier folgt die eigentliche Bearbeitungs-Fläche
$pinTable_row = 0;
foreach ($nodes as $nodeItem) { // Anzahl an Gesamt-Brücken-Elementen (Dies ist Wichtig, da appliedPinRowNumber ein Funktionsparameter ist, damit JS weiß, an welcher Stelle ein neues Element mit welchem Index erstellt werden muss!)
$pinTable_row++;
}
$appliedPinRowNumber = $pinTable_row;
// im Folgenden die Eingabefelder anzeigen (mit aufsteigender ID)
$pinTable_row = 0;
foreach ($nodes as $nodeItem) {
echo '
<div class="row" id="pinRow_' . $pinTable_row . '">
<span>' . $nodeItem[0] . '</span>
<img src="/vendor/icons/data-transfer-both.svg" height="30px" />
<span>' . $nodeItem[1] . '</span>
<img style="transform: rotate(0deg); padding-top: 17.5px;" src="/vendor/icons/trash.svg" onclick="removePin(' . $pinTable_row . ')" height="30px"/>
</div>';
$pinTable_row++;
}
?>
</div>
<button hidden id="bridge-editor-edit" value=""></button>
<div class="save-button" onclick="save('bridge-editor','add')"><img src="/vendor/icons/floppy-disk.svg" \>Speichern</div>
<?php
break;
case "edit": // Bestehende Brücke bearbeiten
?>
<div class="content-header">Brücken-Editor - Bearbeiten</div>
<div class="plug-table">
<?php
$settings = json_decode(file_get_contents("../settings.json"), true);
$plug = $settings["plug"]; //$plug ist die plug-ID!
$result = $db->query("
SELECT * FROM bridges WHERE plug_id = '" . $plug . "' AND id = '" . $meta . "';
");
$result = $result->fetchArray(SQLITE3_ASSOC);
// Skelettstruktur: Die "Row" sorgt hier für das typische Layout, insbesodere für die Darstellung der Brückennummer
?>
<div class="row">
<?php
print('
<div class="label">
<span>' . $result["id"] . '</span>
</div>'); // Brückennummer
$nodes_url = [];
$nodes = $db->query("
SELECT node_from,node_to
FROM nodes WHERE required_by = '". $result['id'] ."';
");
while ($node = $nodes->fetchArray(SQLITE3_ASSOC)) {
$nodes_url[] = [$node['node_from'], $node['node_to']];
}
$url = '../stecker.php?data=' . urlencode(json_encode($nodes_url)); // URL parsen
$nodes = $nodes_url; // die Nodes speichern (hier stecken alle Daten drin)
?>
</div>
<canvas id="bridge-editor-img" meta="<?php echo urlencode(json_encode($nodes_url)); ?>" style="background-image: url('<?php echo $url; ?>');" width="500" height="100"></canvas>
<script>
// Dieses Skript ist zum Großteil aus dem Internet kopiert, jedoch dann an die eigenen Bedürfnisse angepasst worden - Quelle: keine Ahnung
var canvas = document.getElementById('bridge-editor-img');
var ctx = canvas.getContext('2d');
var offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = canvas.width;
offscreenCanvas.height = canvas.height;
var offCtx = offscreenCanvas.getContext('2d');
var rects = [
// Obere Zeile
{id: 31, x: 405, y: 20}, {id: 32, x: 370, y: 20}, {id: 33, x: 335, y: 20},
{id: 34, x: 300, y: 20}, {id: 35, x: 265, y: 20}, {id: 36, x: 230, y: 20},
{id: 37, x: 195, y: 20}, {id: 38, x: 160, y: 20}, {id: 39, x: 125, y: 20},
{id: 30, x: 70, y: 20},
// Mittlere Zeile
{id: 21, x: 405, y: 44}, {id: 22, x: 370, y: 44}, {id: 23, x: 335, y: 44},
{id: 24, x: 300, y: 44}, {id: 25, x: 265, y: 44}, {id: 26, x: 220, y: 44},
{id: 27, x: 185, y: 44}, {id: 28, x: 150, y: 44}, {id: 29, x: 115, y: 44},
{id: 20, x: 70, y: 44},
// Untere Zeile
{id: 11, x: 405, y: 68}, {id: 12, x: 370, y: 68}, {id: 13, x: 335, y: 68},
{id: 14, x: 300, y: 68}, {id: 15, x: 265, y: 68}, {id: 16, x: 230, y: 68},
{id: 17, x: 195, y: 68}, {id: 18, x: 160, y: 68}, {id: 19, x: 125, y: 68},
{id: 10, x: 70, y: 68}
];
var colorID = 0;
var RECT_WIDTH = 25;
var RECT_HEIGHT = 10;
var drawing = false;
var startPoint = null;
function getCenterIfInRect(x, y) {
for (var rect of rects) {
if (
x >= rect.x &&
x <= rect.x + RECT_WIDTH &&
y >= rect.y &&
y <= rect.y + RECT_HEIGHT
) {
return {
x: rect.x + RECT_WIDTH / 2,
y: rect.y + RECT_HEIGHT / 2,
id: rect.id
};
}
}
return null;
}
canvas.addEventListener('mousedown', (e) => {
var rect = canvas.getBoundingClientRect();
var mouseX = e.clientX - rect.left;
var mouseY = e.clientY - rect.top;
var center = getCenterIfInRect(mouseX, mouseY);
if (center) {
startPoint = center;
drawing = true;
}
});
canvas.addEventListener('mousemove', (e) => {
if (!drawing || !startPoint) return;
var rect = canvas.getBoundingClientRect();
var mouseX = e.clientX - rect.left;
var mouseY = e.clientY - rect.top;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(offscreenCanvas, 0, 0);
ctx.beginPath();
ctx.moveTo(startPoint.x, startPoint.y);
ctx.lineTo(mouseX, mouseY);
ctx.strokeStyle = "red";
offCtx.lineWidth = 3;
ctx.stroke();
});
canvas.addEventListener('mouseup', (e) => {
if (!drawing || !startPoint) return;
var rect = canvas.getBoundingClientRect();
var mouseX = e.clientX - rect.left;
var mouseY = e.clientY - rect.top;
var endPoint = getCenterIfInRect(mouseX, mouseY);
drawing = false;
if (endPoint && startPoint.id !== endPoint.id) {
connectPins(startPoint.id, endPoint.id, "canvas");
ctx.clearRect(0, 0, canvas.width, canvas.height);
} else {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(offscreenCanvas, 0, 0);
}
startPoint = null;
});
</script>
<?php
echo '
</div>
<div class="pin-table">'; // Hier folgt die eigentliche Bearbeitungs-Fläche
$pinTable_row = 0;
foreach ($nodes as $nodeItem) { // Anzahl an Gesamt-Brücken-Elementen (Dies ist Wichtig, da appliedPinRowNumber ein Funktionsparameter ist, damit JS weiß, an welcher Stelle ein neues Element mit welchem Index erstellt werden muss!)
$pinTable_row++;
}
$appliedPinRowNumber = $pinTable_row;
// im Folgenden die Eingabefelder anzeigen (mit aufsteigender ID)
$pinTable_row = 0;
foreach ($nodes as $nodeItem) {
echo '
<div class="row" id="pinRow_' . $pinTable_row . '">
<span>' . $nodeItem[0] . '</span>
<img src="/vendor/icons/data-transfer-both.svg" height="30px" />
<span>' . $nodeItem[1] . '</span>
<img style="transform: rotate(0deg); padding-top: 17.5px;" src="/vendor/icons/trash.svg" onclick="removePin(' . $pinTable_row . ')" height="30px"/>
</div>';
$pinTable_row++;
}
?>
</div>
<button id="bridge-editor-edit" value="" onclick="save('bridge-editor','edit','<?php echo $meta; ?>')">Speichern</button>
<?php
break;
default: // Standard: Übersicht
?>
<div class="content-header">Brücken-Editor - Übersicht</div>
<div class="action-menu">
<img src="/vendor/icons/plus.svg" onclick="window.location.href='#bridge-editor'; pageload('add');" />
</div>
<div class="plug-table">
<?php
$settings = json_decode(file_get_contents("../settings.json"), true);
$plug = $settings["plug"]; //$plug ist die plug-ID!
$result = $db->query("SELECT * FROM bridges WHERE plug_id = '" . $plug . "';");
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
?>
<div class="row">
<?php
print('
<div class="label">
<span>' . $row['id'] . '</span>
</div>');
$nodes_url = [];
$nodes = $db->query("
SELECT node_from,node_to
FROM nodes WHERE required_by = ". $row['id'] .";
");
while ($node = $nodes->fetchArray(SQLITE3_ASSOC)) {
$nodes_url[] = [$node['node_from'], $node['node_to']];
}
$url = '../stecker.php?data=' . urlencode(json_encode($nodes_url)); // URL parsen
print('<img id="bridge-editor-img" src="' . $url . '" />');
print('
<div class="options">
<img src="/vendor/icons/edit-pencil.svg" onclick="window.location.href=\'#bridge-editor\'; pageload(\'edit\',\'' . $row["id"] . '\');"/>
<img src="/vendor/icons/trash.svg" onclick="if(confirm(\'Sicher? Diese Änderung kann nicht rückgängig gemacht werden!\') == true){save(\'bridge-editor\',\'remove\',\'' . $row["id"] . '\')}" />
</div>
');
?>
</div>
<?php
}
$result = $db->query("SELECT COUNT(*) as anzahl FROM bridges WHERE plug_id = '" . $plug . "';");
$row = $result->fetchArray(SQLITE3_ASSOC);
$number = $row['anzahl'];
if($number <= 0) {
print("<p align='center'>Es sind keine Brücken für diesen Stecker gespeichert.<br>Eventuell muss ein anderer Stecker gewählt werden.</p>");
}
?>
</div>
<?php
break;
}