diff --git a/src/pygui/ISC/HomePage.qml b/src/pygui/ISC/HomePage.qml index 83574d2..3c6ba26 100644 --- a/src/pygui/ISC/HomePage.qml +++ b/src/pygui/ISC/HomePage.qml @@ -323,6 +323,7 @@ Rectangle { label: "READ MEMORY" iconSource: "../icons/read.svg" Layout.fillWidth: true + enabled: root.waferDetected onClicked: deviceController.readMemoryAsync() } @@ -331,6 +332,7 @@ Rectangle { iconSource: "../icons/erase.svg" Layout.fillWidth: true destructive: true + enabled: root.waferDetected onClicked: deviceController.eraseMemory( deviceController.selectedPort) } diff --git a/src/pygui/ISC/Tabs/StatusTab.qml b/src/pygui/ISC/Tabs/StatusTab.qml index 7e5dfb8..4753ac4 100644 --- a/src/pygui/ISC/Tabs/StatusTab.qml +++ b/src/pygui/ISC/Tabs/StatusTab.qml @@ -4,37 +4,106 @@ import QtQuick.Controls import QtQuick.Dialogs import ISC -// ===== Status Tab ===== -// Shows connection status, wafer info, and activity log. -// Initially visible — displays connection status and activity log from start. +// ===== Status Tab — Bento Grid Dashboard ===== +// ROW 1: Connection Status (65%) | Cycles Completed (35%) +// ROW 2: Wafer & Sensor + Directory (65%) | Total Runtime (35%) +// ROW 3: Activity Log (100%, fills remaining) ColumnLayout { id: root anchors.fill: parent anchors.margins: Theme.panelPadding - spacing: Theme.rightPaneGap + spacing: 8 - property alias waferFamilyCode: waferInfoFamily.text - property alias waferSerialNumber: waferSerial.text - property alias waferSensorCount: waferSensors.text - property alias waferRuntime: waferRuntime.text - property alias waferCycles: waferCycles.text - property bool waferDetected: false + // ── Reusable Inline Components ── + component StatCard : Rectangle { + property alias value: valueText.text + property alias label: labelText.text + property bool active: root.waferDetected + property int valSize: active ? Theme.font3xl : Theme.font2xl + + Layout.fillWidth: true + Layout.fillHeight: true + color: Theme.cardBackground + border.color: Theme.cardBorder + border.width: 1 + radius: Theme.radiusSm + + ColumnLayout { + anchors.centerIn: parent + spacing: 4 + Text { + id: valueText + color: active ? Theme.headingColor : Theme.sideMutedText + font.pixelSize: valSize + font.weight: Font.Bold + font.family: Theme.uiFontFamily + Layout.alignment: Qt.AlignHCenter + } + Text { + id: labelText + color: Theme.sideMutedText + font.pixelSize: Theme.fontXs + font.weight: Font.Medium + font.letterSpacing: 1.2 + font.family: Theme.uiFontFamily + Layout.alignment: Qt.AlignHCenter + } + } + } + + component GridCell : ColumnLayout { + property alias label: labelText.text + property alias value: valueText.text + property bool isRight: false + property bool active: root.waferDetected + + spacing: 1 + Layout.alignment: isRight ? Qt.AlignRight : Qt.AlignLeft + + Text { + id: labelText + color: Theme.sideMutedText + font.pixelSize: Theme.fontXs + font.family: Theme.uiFontFamily + Layout.alignment: isRight ? Qt.AlignRight : Qt.AlignLeft + } + Text { + id: valueText + color: active ? Theme.headingColor : Theme.sideMutedText + font.pixelSize: Theme.fontMd + font.weight: Font.Bold + font.family: Theme.uiFontFamily + Layout.alignment: isRight ? Qt.AlignRight : Qt.AlignLeft + } + } + + // ── Aliases for external wiring ── + property alias waferFamilyCode: waferInfoFamilyCell.value + property alias waferSerialNumber: waferSerialCell.value + property alias waferSensorCount: waferSensorsCell.value + property alias waferRuntime: runtimeCard.value + property alias waferCycles: waferCyclesCell.value + property bool waferDetected: { + var info = deviceController.lastWaferInfo; + return info && info.length > 0 && info[0] !== ""; + } - // Data summary after parse property int dataRows: 0 property int dataCols: 0 property string csvPath: "" property bool dataParsed: false + readonly property bool isConnected: deviceController.connectionStatus === "Connected" + readonly property bool isBusy: deviceController.connectionStatus.endsWith("...") + readonly property string portName: deviceController.selectedPort || "—" + function cleanFolderUrl(url) { return decodeURIComponent(String(url).replace(/^file:\/\//, "")); } - function currentFamilyCode() { var info = deviceController.lastWaferInfo; return info && info.length > 0 ? (info[0] || "") : ""; } - function parseAndSavePendingRead() { deviceController.parseAndSaveData(root.currentFamilyCode(), deviceController.selectedPort || ""); } @@ -48,417 +117,491 @@ ColumnLayout { } } - ColumnLayout { + // ═══════════════════════════════════════════════════════════════════════ + // ROW 1: Connection Status (100%) + // ═══════════════════════════════════════════════════════════════════════ + RowLayout { Layout.fillWidth: true - Layout.fillHeight: true - spacing: Theme.rightPaneGap + Layout.preferredHeight: 90 + Layout.maximumHeight: 90 + spacing: 8 - // --- Connection Status --- Rectangle { Layout.fillWidth: true - Layout.preferredHeight: 92 + Layout.fillHeight: true color: Theme.cardBackground - border.color: { - if (deviceController.connectionStatus === "Connected") - return Theme.statusSuccessColor; - if (deviceController.connectionStatus === "Disconnected") - return Theme.statusErrorColor; - return Theme.cardBorder; - } + border.color: root.isConnected ? Theme.statusSuccessColor : (root.isBusy ? Theme.statusWarningColor : Theme.statusErrorColor) + border.width: 1 radius: Theme.radiusSm ColumnLayout { - anchors.fill: parent - anchors.margins: Theme.panelPadding - spacing: 4 + id: connStatusCol + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: Theme.panelPadding + anchors.rightMargin: Theme.panelPadding + spacing: 8 Text { - text: deviceController.connectionStatus - color: { - if (deviceController.connectionStatus === "Connected") - return Theme.statusSuccessColor; - if (deviceController.connectionStatus === "Disconnected") - return Theme.statusErrorColor; - return Theme.bodyColor; - } - font.bold: true - font.pixelSize: Theme.fontLg - Layout.fillWidth: true - } - - Text { - text: "Port: " + (deviceController.selectedPort || "None selected") - color: Theme.bodyColor - font.pixelSize: Theme.fontMd - Layout.fillWidth: true + text: "CONNECTION STATUS" + color: Theme.sideMutedText + font.pixelSize: Theme.fontXs + font.weight: Font.Medium + font.letterSpacing: 1.2 + font.family: Theme.uiFontFamily } RowLayout { Layout.fillWidth: true + spacing: 0 + + ColumnLayout { + spacing: 1 + Text { + text: "HOST PC" + color: Theme.sideMutedText + font.pixelSize: Theme.fontXs + font.family: Theme.uiFontFamily + } + Text { + text: "localhost" + color: Theme.headingColor + font.pixelSize: Theme.fontMd + font.weight: Font.Bold + font.family: Theme.uiFontFamily + } + } + + Item { + Layout.fillWidth: true + implicitHeight: 22 + + Row { + anchors.centerIn: parent + spacing: 5 + + Repeater { + model: 4 + Rectangle { + width: 4; height: 4; radius: 2 + anchors.verticalCenter: parent.verticalCenter + color: root.isConnected ? Theme.statusSuccessColor : (root.isBusy ? Theme.statusWarningColor : Theme.sideMutedText) + opacity: (root.isConnected || root.isBusy) ? 1.0 : 0.3 + + SequentialAnimation on opacity { + running: root.isConnected || root.isBusy + loops: Animation.Infinite + NumberAnimation { to: 0.3; duration: 1400 } + NumberAnimation { to: 1.0; duration: 1400 } + } + } + } + + Rectangle { + anchors.verticalCenter: parent.verticalCenter + width: statusPillText.implicitWidth + 16 + height: 20 + radius: 10 + color: root.isConnected ? Theme.statusSuccessColor : (root.isBusy ? Theme.statusWarningColor : Theme.statusErrorColor) + + Text { + id: statusPillText + anchors.centerIn: parent + text: root.isConnected ? "ACTIVE" : (root.isBusy ? deviceController.connectionStatus.replace("...", "").toUpperCase() : "INACTIVE") + color: "#111111" + font.pixelSize: Theme.fontXs + font.weight: Font.Bold + font.family: Theme.uiFontFamily + font.letterSpacing: 0.6 + } + } + + Repeater { + model: 4 + Rectangle { + width: 4; height: 4; radius: 2 + anchors.verticalCenter: parent.verticalCenter + color: root.isConnected ? Theme.statusSuccessColor : (root.isBusy ? Theme.statusWarningColor : Theme.sideMutedText) + opacity: (root.isConnected || root.isBusy) ? 1.0 : 0.3 + + SequentialAnimation on opacity { + running: root.isConnected || root.isBusy + loops: Animation.Infinite + NumberAnimation { to: 0.3; duration: 1400 } + NumberAnimation { to: 1.0; duration: 1400 } + } + } + } + } + } + + ColumnLayout { + spacing: 1 + Text { + text: "COM PORT" + color: Theme.sideMutedText + font.pixelSize: Theme.fontXs + font.family: Theme.uiFontFamily + Layout.alignment: Qt.AlignRight + } + Text { + text: root.portName + color: root.isConnected ? Theme.statusSuccessColor : Theme.headingColor + font.pixelSize: Theme.fontMd + font.weight: Font.Bold + font.family: Theme.uiFontFamily + Layout.alignment: Qt.AlignRight + } + } + } + } + } + } + + // ═══════════════════════════════════════════════════════════════════════ + // ROW 2: Wafer & Sensor + Directory (65%) | Total Runtime (35%) + // ═══════════════════════════════════════════════════════════════════════ + RowLayout { + Layout.fillWidth: true + Layout.preferredHeight: 90 + Layout.maximumHeight: 90 + spacing: 8 + + RowLayout { + Layout.preferredWidth: 65 + Layout.fillWidth: true + Layout.fillHeight: true + spacing: 8 + + Rectangle { + Layout.fillWidth: true + Layout.fillHeight: true + color: Theme.cardBackground + border.color: Theme.cardBorder + border.width: 1 + radius: Theme.radiusSm + + ColumnLayout { + anchors.fill: parent + anchors.margins: Theme.panelPadding + spacing: 6 + + ColumnLayout { + Layout.fillWidth: true + spacing: 2 + + Text { + text: "DIRECTORY" + color: Theme.sideMutedText + font.pixelSize: Theme.fontMd + font.weight: Font.Medium + font.letterSpacing: 1.2 + font.family: Theme.uiFontFamily + } + Text { + text: deviceController.saveDataDir || "Not configured" + color: Theme.bodyColor + font.pixelSize: Theme.fontSm + font.family: Theme.uiFontFamily + font.italic: true + opacity: 0.7 + elide: Text.ElideMiddle + Layout.fillWidth: true + } + } + + RowLayout { + Layout.fillWidth: true + spacing: 8 + + Button { + id: browseBtn + text: "Browse" + font.pixelSize: Theme.fontSm + font.weight: Font.Medium + font.family: Theme.uiFontFamily + implicitHeight: 24 + implicitWidth: 60 + hoverEnabled: true + background: Rectangle { + color: browseBtn.hovered ? Theme.buttonNeutralHover : Theme.buttonNeutralBackground + border.color: Theme.cardBorder + border.width: 1 + radius: Theme.radiusSm + } + contentItem: Text { + text: browseBtn.text + color: Theme.bodyColor + font: browseBtn.font + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + onClicked: saveDirDialog.open() + } + + Item { Layout.fillWidth: true } + + Row { + spacing: 4 + visible: root.isConnected + Rectangle { + width: 6; height: 6; radius: 3 + color: Theme.statusSuccessColor + anchors.verticalCenter: parent.verticalCenter + } + } + + Rectangle { + visible: root.csvPath !== "" + width: sessionSavedLabel.implicitWidth + 12 + height: 18 + radius: 4 + color: Theme.fieldBackground + border.color: Theme.sideBorder + border.width: 1 + + Text { + id: sessionSavedLabel + anchors.centerIn: parent + text: "SESSION SAVED" + color: Theme.sideMutedText + font.pixelSize: Theme.fontXs + font.weight: Font.Bold + font.family: Theme.uiFontFamily + font.letterSpacing: 0.6 + } + } + } + } + } + + Rectangle { + Layout.fillWidth: true + Layout.fillHeight: true + color: Theme.cardBackground + border.color: Theme.cardBorder + border.width: 1 + radius: Theme.radiusSm + + ColumnLayout { + anchors.fill: parent + anchors.margins: Theme.panelPadding + spacing: 8 + + Item { + Layout.fillWidth: true + Layout.fillHeight: true + + GridLayout { + anchors.fill: parent + columns: 2 + rowSpacing: 6 + columnSpacing: 16 + + GridCell { + id: waferInfoFamilyCell + label: "Family Code" + value: { + var info = deviceController.lastWaferInfo; + return (info && info.length > 0 && info[0]) ? info[0] : "—"; + } + } + GridCell { + id: waferCyclesCell + label: "Cycles Completed" + value: { + var info = deviceController.lastWaferInfo; + return (info && info.length > 5 && info[5] !== undefined) ? String(info[5]) : "—"; + } + isRight: true + active: root.waferDetected + } + GridCell { + id: waferSerialCell + label: "Serial" + value: { + var info = deviceController.lastWaferInfo; + return (info && info.length > 1 && info[1]) ? info[1] : "—"; + } + } + GridCell { + id: waferSensorsCell + label: "Sensors" + value: { + var info = deviceController.lastWaferInfo; + return (info && info.length > 2 && info[2]) ? String(info[2]) : "—"; + } + isRight: true + } + } + } + } + } + } + + StatCard { + id: runtimeCard + Layout.preferredWidth: 35 + value: { + var info = deviceController.lastWaferInfo; + return (info && info.length > 4 && info[4] !== undefined) ? info[4] + "s" : "—"; + } + label: "TOTAL RUNTIME" + } + } + + // ═══════════════════════════════════════════════════════════════════════ + // ROW 3: Activity Log — ALWAYS visible (fills remaining height) + // ═══════════════════════════════════════════════════════════════════════ + Rectangle { + Layout.fillWidth: true + Layout.fillHeight: true + color: Theme.cardBackground + border.color: Theme.cardBorder + border.width: 1 + radius: Theme.radiusMd + clip: true + + ColumnLayout { + anchors.fill: parent + spacing: 0 + + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: 36 + color: Theme.subtleSectionBackground + + RowLayout { + anchors.fill: parent + anchors.leftMargin: Theme.panelPadding + anchors.rightMargin: Theme.panelPadding spacing: 8 - Layout.alignment: Qt.AlignVCenter Text { - text: "Save dir: " + (deviceController.saveDataDir || "None selected") - color: Theme.bodyColor + text: "📄" font.pixelSize: Theme.fontSm - opacity: 0.7 + visible: root.csvPath !== "" + Layout.alignment: Qt.AlignVCenter + } + + Label { + text: root.csvPath !== "" ? root.csvPath.split("/").pop() : "ACTIVITY LOG" + color: Theme.bodyColor + font.pixelSize: root.csvPath !== "" ? Theme.fontMd : Theme.fontSm + font.letterSpacing: root.csvPath !== "" ? 0 : 1.8 + font.weight: Font.Medium + font.family: Theme.uiFontFamily elide: Text.ElideMiddle Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter } Button { - id: browseBtn - text: "BROWSE..." - font.pixelSize: Theme.font2xs - font.weight: Font.Medium - implicitHeight: 20 - implicitWidth: 65 + id: refreshSessionBtn + text: "Refresh" + font.pixelSize: Theme.fontSm + font.family: Theme.uiFontFamily + implicitHeight: 24 hoverEnabled: true background: Rectangle { - color: parent.hovered ? Theme.buttonNeutralHover : Theme.buttonNeutralBackground - border.color: Theme.cardBorder - border.width: 1 + color: refreshSessionBtn.hovered ? Theme.buttonNeutralHover : "transparent" radius: Theme.radiusSm } contentItem: Text { - text: parent.text + text: refreshSessionBtn.text color: Theme.bodyColor - font: parent.font + font: refreshSessionBtn.font horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } - onClicked: saveDirDialog.open() - } - } - } - } - - // --- Wafer Info --- - GroupBox { - title: "Wafer Information" - visible: root.waferDetected - Layout.fillWidth: true - - ColumnLayout { - anchors.fill: parent - anchors.margins: Theme.panelPadding - spacing: 8 - - RowLayout { - Layout.fillWidth: true - spacing: Theme.rightPaneGap - - ColumnLayout { - Layout.fillWidth: true - spacing: 4 - Text { - text: "Family Code" - color: Theme.subheadingColor - font.pixelSize: Theme.fontSm - } - Text { - id: waferInfoFamily - text: "—" - color: Theme.bodyColor - font.pixelSize: Theme.fontLg - font.bold: true - } + onClicked: deviceController.clearSession() } - ColumnLayout { - Layout.fillWidth: true - spacing: 4 - Text { - text: "Serial Number" - color: Theme.subheadingColor - font.pixelSize: Theme.fontSm - } - Text { - id: waferSerial - text: "—" - color: Theme.bodyColor - font.pixelSize: Theme.fontLg - font.bold: true - } - } - - ColumnLayout { - Layout.fillWidth: true - spacing: 4 - Text { - text: "Sensor Count" - color: Theme.subheadingColor - font.pixelSize: Theme.fontSm - } - Text { - id: waferSensors - text: "—" - color: Theme.bodyColor - font.pixelSize: Theme.fontLg - font.bold: true - } - } - } - - RowLayout { - Layout.fillWidth: true - spacing: Theme.rightPaneGap - - ColumnLayout { - Layout.fillWidth: true - spacing: 4 - Text { - text: "Runtime" - color: Theme.subheadingColor - font.pixelSize: Theme.fontSm - } - Text { - id: waferRuntime - text: "—" - color: Theme.bodyColor - font.pixelSize: Theme.fontLg - font.bold: true - } - } - - ColumnLayout { - Layout.fillWidth: true - spacing: 4 - Text { - text: "Cycles" - color: Theme.subheadingColor - font.pixelSize: Theme.fontSm - } - Text { - id: waferCycles - text: "—" - color: Theme.bodyColor - font.pixelSize: Theme.fontLg - font.bold: true - } - } - } - } - } - - // --- Data Summary (shown after parse) --- - GroupBox { - title: "Data Summary" - visible: root.dataParsed - Layout.fillWidth: true - - RowLayout { - anchors.fill: parent - anchors.margins: Theme.panelPadding - spacing: Theme.rightPaneGap - - ColumnLayout { - Layout.fillWidth: true - spacing: 4 - Text { - text: "Rows" - color: Theme.subheadingColor + Button { + id: clearLogBtn + text: "Clear" font.pixelSize: Theme.fontSm - } - Text { - text: String(root.dataRows) - color: Theme.bodyColor - font.pixelSize: Theme.fontLg - font.bold: true + font.family: Theme.uiFontFamily + implicitHeight: 24 + hoverEnabled: true + background: Rectangle { + color: clearLogBtn.hovered ? Theme.buttonNeutralHover : "transparent" + radius: Theme.radiusSm + } + contentItem: Text { + text: clearLogBtn.text + color: Theme.bodyColor + font: clearLogBtn.font + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + onClicked: deviceController.clearActivityLog() } } - ColumnLayout { - Layout.fillWidth: true - spacing: 4 - Text { - text: "Sensors" - color: Theme.subheadingColor - font.pixelSize: Theme.fontSm - } - Text { - text: String(root.dataCols) - color: Theme.bodyColor - font.pixelSize: Theme.fontLg - font.bold: true - } - } - - ColumnLayout { - Layout.fillWidth: true - spacing: 4 - Text { - text: "CSV" - color: Theme.subheadingColor - font.pixelSize: Theme.fontSm - } - Text { - text: root.csvPath - color: Theme.bodyColor - font.pixelSize: Theme.fontSm - elide: Text.ElideMiddle - } - } - } - } - - // --- Activity Log --- - Rectangle { - Layout.fillWidth: true - Layout.fillHeight: true - color: Theme.cardBackground - border.color: Theme.cardBorder - radius: Theme.radiusMd - clip: true - - ColumnLayout { - anchors.fill: parent - spacing: 0 - - // Header Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: 40 - color: Theme.subtleSectionBackground - - RowLayout { - anchors.fill: parent - anchors.leftMargin: Theme.panelPadding - anchors.rightMargin: Theme.panelPadding - - Label { - text: "ACTIVITY LOG" - color: Theme.bodyColor - font.pixelSize: Theme.fontXs - font.letterSpacing: 1.8 - font.weight: Font.Medium - Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter - } - - Button { - text: "REFRESH SESSION" - font.pixelSize: Theme.fontXs - implicitHeight: 24 - hoverEnabled: true - background: Rectangle { - color: parent.hovered ? Theme.buttonNeutralHover : "transparent" - radius: Theme.radiusSm - } - contentItem: Text { - text: parent.text - color: Theme.bodyColor - font: parent.font - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - } - onClicked: deviceController.clearSession() - } - - Button { - text: "CLEAR LOG" - font.pixelSize: Theme.fontXs - implicitHeight: 24 - hoverEnabled: true - background: Rectangle { - color: parent.hovered ? Theme.buttonNeutralHover : "transparent" - radius: Theme.radiusSm - } - contentItem: Text { - text: parent.text - color: Theme.bodyColor - font: parent.font - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - } - onClicked: deviceController.clearActivityLog() - } - } - - Rectangle { - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - height: 1 - color: Theme.cardBorder - } - } - - ScrollView { - Layout.fillWidth: true - Layout.fillHeight: true - Layout.margins: Theme.panelPadding - clip: true - - TextArea { - id: activityLog - width: parent.width - text: qsTr("Welcome — use the side rail to detect a wafer, or import data to review.") - readOnly: true - font.family: "monospace" - font.pixelSize: Theme.fontSm - wrapMode: TextArea.WordWrap - color: Theme.bodyColor - background: null - } + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + height: 1 + color: Theme.cardBorder } } - Connections { - target: deviceController - function onActivityLogUpdated(newLog) { - activityLog.text = newLog; + ScrollView { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.margins: Theme.panelPadding + clip: true + + TextArea { + id: activityLog + width: parent.width + text: qsTr("Welcome — use the side rail to detect a wafer, or import data to review.") + readOnly: true + font.family: "monospace" + font.pixelSize: Theme.fontSm + wrapMode: TextArea.WordWrap + color: Theme.bodyColor + background: null } } } + + Connections { + target: deviceController + function onActivityLogUpdated(newLog) { + activityLog.text = newLog ? newLog : qsTr("Welcome — use the side rail to detect a wafer, or import data to review."); + } + } } - // --- Signal Handlers --- + // ═══════════════════════════════════════════════════════════════════════ + // SIGNAL HANDLERS + // ═══════════════════════════════════════════════════════════════════════ Connections { target: deviceController - function onLogMessage(message) { if (message == "CHOOSE_SAVE_DIR") { saveDirDialog.open(); } } - - // Any operation start (detect/read/erase/debug) latches the panel on. - function onPortsUpdated() { - // Status tab always visible now - } - + function onPortsUpdated() {} function onDetectResult(result) { - if (result && result.familyCode) { - root.waferDetected = true; - waferInfoFamily.text = result.familyCode; - waferSerial.text = result.serialNumber; - waferSensors.text = String(result.sensorCount); - waferRuntime.text = result.runtime + "s"; - waferCycles.text = String(result.cycleCount); + if (!result) { + root.dataParsed = false; + root.dataRows = 0; + root.dataCols = 0; + root.csvPath = ""; } - // On failure, keep the last displayed wafer info and do not change waferDetected. } - function onStatusRestored() { - // Show restored wafer info if available - var info = deviceController.lastWaferInfo; - if (info && info.length > 0) { - root.waferDetected = true; - waferInfoFamily.text = info[0] || "—"; - waferSerial.text = info[1] || "—"; - waferSensors.text = String(info[2] || 0); - waferRuntime.text = (info[3] || 0) + "s"; - waferCycles.text = String(info[4] || 0); - } - // Show data summary if data was previously parsed if (deviceController.dataRowCount > 0) { root.dataParsed = true; root.dataRows = deviceController.dataRowCount; root.dataCols = deviceController.dataColCount; - root.csvPath = ""; // CSV path not persisted as full path, just show it was parsed + root.csvPath = ""; } } } @@ -470,7 +613,6 @@ ColumnLayout { root.dataRows = 0; root.dataCols = 0; root.csvPath = ""; - if (result && result.success === true) saveDirDialog.open(); }