# KX-Bridge Theme – JavaScript-Hooks Referenz für eigenes Theme-Layout (`index.html` + gemeinsames `app.js`). **Quelle:** `default/index.html` und `default/app.js` **Stand:** Theme-Struktur mit getrennten Dateien (`index.html`, `style.css`, `app.js`) --- ## Hinweise für Theme-Entwickler - Alle `onclick`-Handler rufen **globale Funktionen** aus `app.js` auf – Namen beibehalten oder in eigenem JS neu binden. - `app.js` wird unter `/kx/ui/app.js` geladen und ist pro Theme austauschbar; die Standard-Implementierung erwartet die Hooks unten. - Dynamisch erzeugtes HTML (AMS-Slots, Datei-Karten, Drucker-Karten) setzt zusätzliche `onclick`-Handler – siehe Abschnitt **Dynamisch aus app.js**. --- ## Globale / Header | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `startReadyFile()` | `#file-ready-btn` | GCode vom Slicer bereit → sofort drucken | | `startReadyFileWithSlots()` | `#file-slots-btn` | Druck mit AMS-Slot-Zuordnung | | `cancelReadyFile()` | `#file-cancel-btn` | Upload-Banner schließen | | `togglePrinterDropdown()` | `#printer-dropdown-btn` | Multi-Drucker-Dropdown | | `toggleTheme()` | Theme-Button | Hell/Dunkel (`data-theme`, localStorage) | | `toggleLang()` | `#lang-btn` | DE/EN umschalten | | `openSettings()` | `#settings-btn` | Einstellungs-Modal | | `toggleConnection()` | `#conn-btn` | MQTT verbinden / trennen | --- ## Einstellungs-Modal (`#settings-modal`) | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `closeSettings()` | Overlay (Backdrop), Schließen-Button | Modal schließen | | `setPoll(1000)` | `#poll-1` | Status-Poll 1 s | | `setPoll(2000)` | `#poll-2` | Status-Poll 2 s | | `setPoll(5000)` | `#poll-5` | Status-Poll 5 s | | `checkUpdate()` | `#btn-update-check` | Update prüfen | | `applyUpdate()` | `#btn-update-apply` | Update installieren | | `saveSettings()` | `#btn-save-settings` | Config speichern → Neustart | **Ohne `onclick` in HTML:** IP-Hinweis für `#s-printer-ip` wird in `app.js` per `addEventListener('input', …)` gebunden. --- ## AMS-Slot bearbeiten (`#slot-edit-modal`) | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `closeSlotEdit()` | Overlay, ✕ | Dialog schließen | | `highlightMatBtn(this.value)` | `#slot-edit-mat` `oninput` | Material-Presets hervorheben | | `saveSlotEdit()` | `#btn-slot-edit-save` | Farbe/Material speichern | **Inline (keine benannte Funktion):** | Code | Element | Zweck | |------|---------|--------| | `document.getElementById('slot-edit-preview').style.background=this.value` | `#slot-edit-color` | Farbvorschau | **Dynamisch aus `app.js`:** | Aufruf | Kontext | |--------|---------| | `openSlotEdit(i)` | Klick auf AMS-Kachel in `#ams-slots` | | `selectMatPreset('PLA'…)` | Material-Preset-Buttons in `#slot-mat-btns` | --- ## Navigation (Sidebar + Bottom-Nav) | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `showPanel('dashboard')` | `#nb-dashboard`, `#bnb-dashboard` | Dashboard | | `showPanel('printers'); loadPrinterTab()` | `#nb-printers`, `#bnb-printers` | Drucker-Tab | | `showPanel('store'); loadStore()` | `#nb-store`, `#bnb-store` | Datei-Browser | | `showPanel('console'); clearLogBadge()` | `#nb-console`, `#bnb-console` | Konsole, Badge leeren | **Erforderliche Panel-IDs:** `panel-dashboard`, `panel-printers`, `panel-store`, `panel-console` **Nav-IDs:** `nb-*` und `bnb-*` mit gleichem Suffix (`dashboard`, `printers`, `store`, `console`) --- ## Dashboard – Kamera | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `setLight()` | `#d-light-toggle` `onchange` | Drucker-Licht | | `toggleCam()` | `#cam-toggle-btn` | Stream starten/stoppen | Intern: `toggleCam()` → `camStart()` / `camStop()` (nur in `app.js`). --- ## Dashboard – Drucksteuerung | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `printAction('pause')` | `#d-btn-pause` | Pausieren | | `printAction('resume')` | `#d-btn-resume` | Fortsetzen | | `confirmCancel()` | `#d-btn-cancel` | Bestätigung → `printAction('cancel')` | --- ## Dashboard – Temperaturen | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `setNozzle()` | Set-Button Nozzle | Zieltemperatur Düse (`#p-nozzle-inp`) | | `setBed()` | Set-Button Bett | Zieltemperatur Bett (`#p-bed-inp`) | **Inline:** Aus-Button setzt Input auf `0`, dann `setNozzle()` bzw. `setBed()`. --- ## Dashboard – Achsensteuerung | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `move(1, 1, getStep())` | Joypad ▲ | Y+ | | `move(1, -1, getStep())` | Joypad ▼ | Y− | | `move(0, -1, getStep())` | Joypad ◀ | X− | | `move(0, 1, getStep())` | Joypad ▶ | X+ | | `move(2, 1, getStep())` | Z ▲ | Z+ | | `move(2, -1, getStep())` | Z ▼ | Z− | | `homeAll()` | Joypad ⌂, Home-All | Referenzfahrt alle Achsen | | `homeZ()` | Home Z | Nur Z | | `homeXY()` | Home XY | Nur X/Y | | `disableMotors()` | Motors Off | Motoren aus | | `setStep(this, 0.1\|1\|5\|10)` | Schrittweiten-Buttons | Jog-Schrittweite | | `getStep()` | in allen `move(…)` | Aktuelle Schrittweite (Hilfsfunktion) | --- ## Dashboard – Druckgeschwindigkeit | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `setSpeed(1)` | `#d-spd-1` | Leise | | `setSpeed(2)` | `#d-spd-2` | Normal | | `setSpeed(3)` | `#d-spd-3` | Sport | --- ## Dashboard – Lüfter | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `setFan()` | `#d-fan` `onchange` | Slider-Wert senden | | `quickFan(0\|25\|50\|75\|100)` | Schnell-Buttons | Vordefinierte Stufen | **Inline:** `#d-fan` `oninput` → `#d-fan-val` aktualisieren. --- ## Dashboard – AMS / Filament | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `amsFeed(1)` | Einziehen | Filament laden | | `amsFeed(2)` | Ausziehen | Filament entladen | **Inline:** `#ams-slot-sel` `oninput` → `#ams-slot-label` („Slot 1…4“). --- ## Drucker-Tab (`#panel-printers`) | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `openAddPrinterDialog()` | „+ Drucker hinzufügen“ | Dialog öffnen | | `loadPrinterTab()` | ↻-Button | Liste neu laden | **Dynamisch:** `removePrinter(id, name)` auf Drucker-Karten in `#printers-grid`. --- ## Datei-Browser (`#panel-store`) | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `loadStore()` | `#store-refresh-btn` | Dateiliste laden | | `renderStore()` | `#store-search`, `#store-filter`, `#store-sort` | Filtern/Sortieren | **Dynamisch:** `storePrint(fileId, filename)`, `storeDelete(fileId)` auf Karten in `#store-grid`. --- ## Konsole (`#panel-console`) | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `renderLog()` | `#log-filter` `oninput`, Clear-Button | Filtern / leeren | | `toggleAutoScroll()` | `#btn-autoscroll` | Auto-Scroll | | `setLogDir('all'\|'rx'\|'tx')` | `#logdir-all`, `#logdir-rx`, `#logdir-tx` | Richtungsfilter | | `setLogTopic('multiColorBox'\|'print'\|'info'\|'status')` | Topic-Buttons | MQTT-Topic | | `onLogScroll()` | `#console-log` `onscroll` | Auto-Scroll bei manuellem Scroll deaktivieren | **Inline Clear:** `consoleLogs=[]; renderLog()` (keine eigene Funktion). --- ## Filament-Dialog (`#filament-dialog`) | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `closeFilamentDialog()` | Overlay, Abbrechen, ✕ | Schließen | | `confirmFilamentPrint()` | „▶ Drucken“ | Slot-Zuordnung bestätigen | Inhalt von `#fd-slots` wird von `openFilamentDialog()` befüllt (nach `startReadyFileWithSlots()` / `storePrint()`). --- ## Drucker-hinzufügen-Dialog (`#add-printer-dialog`) | Aufruf | HTML-Element | Kontext | |--------|--------------|---------| | `closeAddPrinterDialog()` | Overlay, Abbrechen, ✕ | Schließen | | `confirmAddPrinter()` | `#apd-confirm` | IP/Name senden → Neustart | --- ## Modal-Backdrop-Muster Mehrere Overlays nutzen: ```html onclick="if(event.target===this)closeSettings()" ``` | Funktion | Modal-ID | |----------|----------| | `closeSettings()` | `#settings-modal` | | `closeSlotEdit()` | `#slot-edit-modal` | | `closeFilamentDialog()` | `#filament-dialog` | | `closeAddPrinterDialog()` | `#add-printer-dialog` | --- ## Funktionen ohne HTML-Hook (automatisch) | Funktion | Wann / wofür | |----------|----------------| | `poll()` | Periodisch `/api/state` – Dashboard-Update | | `applyState()` | Poll-Daten ins DOM schreiben | | `initPrinters()` | Multi-Drucker-Liste beim Start | | `renderPrinterDropdown()` | Header-Dropdown | | `applyLang()` | Übersetzungen (Start + nach `toggleLang()`) | | `updateConnBtn()` | Verbindungs-Button | | `updateHistory()` / `drawChart()` | Temperatur-Verlauf `#d-chart` | | `connect()` (SSE) | Live-Server-Log | | `openFilamentDialog()` | Multi-Farben-Druck | | `openSlotEdit()` | AMS-Kacheln | | `storePrint()` / `storeDelete()` | Datei-Karten | | `removePrinter()` | Drucker-Karten | | `camStart()` / `camStop()` | Kamera (auch auto bei Druckstart) | --- ## CSS-Klassen (keine IDs, aber von app.js genutzt) | Klasse | Verwendung | |--------|------------| | `.panel` | Tab-Panels (`showPanel`) | | `.nav-btn`, `.bnav-btn` | Navigation active-State | | `.nav-text` | Sidebar-Label (i18n) | | `.lbl-set`, `.lbl-off` | Temp-Button-Texte | | `.lbl-home-z`, `.lbl-home-xy`, `.lbl-home-all`, `.lbl-disable-motors` | Home-Buttons | | `.lbl-step` | Schrittweiten-Label | | `.lbl-feed`, `.lbl-unload` | AMS-Buttons | | `.temp-input` | Placeholder i18n | | `.step-btn` | Schrittweiten-Auswahl | | `.poll-btn` | Poll-Intervall | | `.log-dir-btn`, `.log-topic-btn` | Log-Filter | | `.mat-preset-btn` | Slot-Material (dynamisch) | | `.ams-slot` | AMS-Kacheln (dynamisch) | --- ## Theme aktivieren ```bash python kobrax_moonraker_bridge.py … --ui-theme default # oder KX_UI_THEME=new1 python kobrax_moonraker_bridge.py … ``` Pro Theme-Ordner: `index.html`, `style.css`, `app.js` unter `web/themes//`.