pragma ComponentBehavior: Bound import QtQuick import QtQuick.Controls import QtQuick.Layouts import Xpl2 ApplicationWindow { id: root // Set from C++ via setInitialProperties (--printheads CLI arg, default 10). required property int demoPhCount height: 1200 title: "Jetting Interface" visible: true width: 900 Component.onCompleted: { for (let i = 1; i <= root.demoPhCount; ++i) phModel.append({ "phId": i, "versionInfo": "", "valid": false }); } ListModel { id: phModel } Connections { function onConnectedChanged() { debugConsole.appendLog(Xpl2Client.connected ? "Connected to proxy" : "Disconnected from proxy"); } function onErrorOccurred(error: string) { debugConsole.appendLog("ERROR: " + error); } function onJcStatusReceived(status) { statusPage.lastJcStatus = status; } function onPhStatusReceived(status) { statusPage.lastPhStatus = status; } function onPhVersionReceived(controllerId: int, printheadId: int, mcuFirmwareVersion: string, mcuHardwareVersion: string, mcuFirmwareVariant: string, fpgaFirmwareVersion: string, fpgaHardwareVersion: string, bootloaderVersion: string) { // A printhead is present only if it reports a non-zero version. // Absent slots reply with all zeros; mcuHardwareVersion and // mcuFirmwareVariant are "00" even on present heads, so they are // excluded from the check (see docs/DISCREPANCIES.md). let isZero = v => parseFloat(v) === 0 || v === ""; let valid = !(isZero(mcuFirmwareVersion) && isZero(fpgaFirmwareVersion) && isZero(fpgaHardwareVersion) && isZero(bootloaderVersion)); let info = valid ? "MCU %1/%2 (%3) | FPGA %4/%5 | Boot %6".arg( mcuFirmwareVersion).arg( mcuHardwareVersion).arg( mcuFirmwareVariant).arg( fpgaFirmwareVersion).arg( fpgaHardwareVersion).arg( bootloaderVersion) : "(Printhead unavailable)"; for (let i = 0; i < phModel.count; ++i) { if (phModel.get(i).phId === printheadId) { phModel.setProperty(i, "versionInfo", info); phModel.setProperty(i, "valid", valid); break; } } } function onShuttingDown() { debugConsole.appendLog("SERVER SHUTTING DOWN"); } function onStatusMessage(message: string) { debugConsole.appendLog(message); } target: Xpl2Client } ColumnLayout { anchors.fill: parent spacing: 0 // --- Connection (always visible) --- GroupBox { Layout.bottomMargin: 0 Layout.fillWidth: true Layout.margins: 16 title: "Connection" RowLayout { anchors.fill: parent TextField { Layout.preferredWidth: 140 placeholderText: "Host" text: Xpl2Client.host onEditingFinished: Xpl2Client.host = text } TextField { Layout.preferredWidth: 70 placeholderText: "Port" text: Xpl2Client.commandPort onEditingFinished: Xpl2Client.commandPort = parseInt(text) } Label { text: Xpl2Client.connected ? "Connected to proxy" : "Disconnected" } Item { Layout.fillWidth: true } Button { text: Xpl2Client.connected ? "Disconnect" : "Connect" onClicked: { if (Xpl2Client.connected) Xpl2Client.disconnectFromProxy(); else Xpl2Client.connectToProxy(); } } } } // --- Tab bar --- TabBar { id: tabBar Layout.fillWidth: true Layout.leftMargin: 16 Layout.rightMargin: 16 TabButton { text: "Commands" } TabButton { text: "Status" } } // --- Swipe view --- SwipeView { id: swipeView Layout.fillHeight: true Layout.fillWidth: true Layout.margins: 16 currentIndex: tabBar.currentIndex onCurrentIndexChanged: tabBar.currentIndex = currentIndex CommandsPage { demoPhCount: root.demoPhCount phModel: phModel } StatusPage { id: statusPage } } // --- Debug Console --- DebugConsole { id: debugConsole Layout.fillWidth: true Layout.preferredHeight: 160 } } }