feat(tabs): update all tab views, dialogs, and session controller
This commit is contained in:
+181
-101
@@ -27,24 +27,24 @@ ColumnLayout {
|
||||
property bool dataParsed: false
|
||||
|
||||
function cleanFolderUrl(url) {
|
||||
return decodeURIComponent(String(url).replace(/^file:\/\//, ""))
|
||||
return decodeURIComponent(String(url).replace(/^file:\/\//, ""));
|
||||
}
|
||||
|
||||
function currentFamilyCode() {
|
||||
var info = deviceController.lastWaferInfo
|
||||
return info && info.length > 0 ? (info[0] || "") : ""
|
||||
var info = deviceController.lastWaferInfo;
|
||||
return info && info.length > 0 ? (info[0] || "") : "";
|
||||
}
|
||||
|
||||
function parseAndSavePendingRead() {
|
||||
deviceController.parseAndSaveData(root.currentFamilyCode(), deviceController.selectedPort || "")
|
||||
deviceController.parseAndSaveData(root.currentFamilyCode(), deviceController.selectedPort || "");
|
||||
}
|
||||
|
||||
FolderDialog {
|
||||
id: saveDirDialog
|
||||
title: "Choose a folder to save."
|
||||
onAccepted: {
|
||||
deviceController.setSaveDataDir(root.cleanFolderUrl(selectedFolder))
|
||||
root.parseAndSavePendingRead()
|
||||
deviceController.setSaveDataDir(root.cleanFolderUrl(selectedFolder));
|
||||
root.parseAndSavePendingRead();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,9 +59,11 @@ ColumnLayout {
|
||||
Layout.preferredHeight: 92
|
||||
color: Theme.cardBackground
|
||||
border.color: {
|
||||
if (deviceController.connectionStatus === "Connected") return Theme.statusSuccessColor
|
||||
if (deviceController.connectionStatus === "Disconnected") return Theme.statusErrorColor
|
||||
return Theme.cardBorder
|
||||
if (deviceController.connectionStatus === "Connected")
|
||||
return Theme.statusSuccessColor;
|
||||
if (deviceController.connectionStatus === "Disconnected")
|
||||
return Theme.statusErrorColor;
|
||||
return Theme.cardBorder;
|
||||
}
|
||||
radius: Theme.radiusSm
|
||||
|
||||
@@ -73,19 +75,21 @@ ColumnLayout {
|
||||
Text {
|
||||
text: deviceController.connectionStatus
|
||||
color: {
|
||||
if (deviceController.connectionStatus === "Connected") return Theme.statusSuccessColor
|
||||
if (deviceController.connectionStatus === "Disconnected") return Theme.statusErrorColor
|
||||
return Theme.bodyColor
|
||||
if (deviceController.connectionStatus === "Connected")
|
||||
return Theme.statusSuccessColor;
|
||||
if (deviceController.connectionStatus === "Disconnected")
|
||||
return Theme.statusErrorColor;
|
||||
return Theme.bodyColor;
|
||||
}
|
||||
font.bold: true
|
||||
font.pixelSize: 16
|
||||
font.pixelSize: Theme.fontLg
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Port: " + (deviceController.selectedPort || "None selected")
|
||||
color: Theme.bodyColor
|
||||
font.pixelSize: 14
|
||||
font.pixelSize: Theme.fontMd
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
@@ -97,7 +101,7 @@ ColumnLayout {
|
||||
Text {
|
||||
text: "Save dir: " + (deviceController.saveDataDir || "None selected")
|
||||
color: Theme.bodyColor
|
||||
font.pixelSize: 12
|
||||
font.pixelSize: Theme.fontSm
|
||||
opacity: 0.7
|
||||
elide: Text.ElideMiddle
|
||||
Layout.fillWidth: true
|
||||
@@ -107,7 +111,7 @@ ColumnLayout {
|
||||
Button {
|
||||
id: browseBtn
|
||||
text: "BROWSE..."
|
||||
font.pixelSize: 9
|
||||
font.pixelSize: Theme.font2xs
|
||||
font.weight: Font.Medium
|
||||
implicitHeight: 20
|
||||
implicitWidth: 65
|
||||
@@ -149,22 +153,52 @@ ColumnLayout {
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 4
|
||||
Text { text: "Family Code"; color: Theme.subheadingColor; font.pixelSize: 12 }
|
||||
Text { id: waferInfoFamily; text: "—"; color: Theme.bodyColor; font.pixelSize: 16; font.bold: true }
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 4
|
||||
Text { text: "Serial Number"; color: Theme.subheadingColor; font.pixelSize: 12 }
|
||||
Text { id: waferSerial; text: "—"; color: Theme.bodyColor; font.pixelSize: 16; font.bold: true }
|
||||
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: 12 }
|
||||
Text { id: waferSensors; text: "—"; color: Theme.bodyColor; font.pixelSize: 16; font.bold: true }
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,15 +209,35 @@ ColumnLayout {
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 4
|
||||
Text { text: "Runtime"; color: Theme.subheadingColor; font.pixelSize: 12 }
|
||||
Text { id: waferRuntime; text: "—"; color: Theme.bodyColor; font.pixelSize: 16; font.bold: true }
|
||||
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: 12 }
|
||||
Text { id: waferCycles; text: "—"; color: Theme.bodyColor; font.pixelSize: 16; font.bold: true }
|
||||
Text {
|
||||
text: "Cycles"
|
||||
color: Theme.subheadingColor
|
||||
font.pixelSize: Theme.fontSm
|
||||
}
|
||||
Text {
|
||||
id: waferCycles
|
||||
text: "—"
|
||||
color: Theme.bodyColor
|
||||
font.pixelSize: Theme.fontLg
|
||||
font.bold: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,22 +257,49 @@ ColumnLayout {
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 4
|
||||
Text { text: "Rows"; color: Theme.subheadingColor; font.pixelSize: 12 }
|
||||
Text { text: String(root.dataRows); color: Theme.bodyColor; font.pixelSize: 16; font.bold: true }
|
||||
Text {
|
||||
text: "Rows"
|
||||
color: Theme.subheadingColor
|
||||
font.pixelSize: Theme.fontSm
|
||||
}
|
||||
Text {
|
||||
text: String(root.dataRows)
|
||||
color: Theme.bodyColor
|
||||
font.pixelSize: Theme.fontLg
|
||||
font.bold: true
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 4
|
||||
Text { text: "Sensors"; color: Theme.subheadingColor; font.pixelSize: 12 }
|
||||
Text { text: String(root.dataCols); color: Theme.bodyColor; font.pixelSize: 16; font.bold: true }
|
||||
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: 12 }
|
||||
Text { text: root.csvPath; color: Theme.bodyColor; font.pixelSize: 12; elide: Text.ElideMiddle }
|
||||
Text {
|
||||
text: "CSV"
|
||||
color: Theme.subheadingColor
|
||||
font.pixelSize: Theme.fontSm
|
||||
}
|
||||
Text {
|
||||
text: root.csvPath
|
||||
color: Theme.bodyColor
|
||||
font.pixelSize: Theme.fontSm
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -241,25 +322,25 @@ ColumnLayout {
|
||||
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: 10
|
||||
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: 10
|
||||
font.pixelSize: Theme.fontXs
|
||||
implicitHeight: 24
|
||||
hoverEnabled: true
|
||||
background: Rectangle {
|
||||
@@ -275,10 +356,10 @@ ColumnLayout {
|
||||
}
|
||||
onClicked: deviceController.clearSession()
|
||||
}
|
||||
|
||||
|
||||
Button {
|
||||
text: "CLEAR LOG"
|
||||
font.pixelSize: 10
|
||||
font.pixelSize: Theme.fontXs
|
||||
implicitHeight: 24
|
||||
hoverEnabled: true
|
||||
background: Rectangle {
|
||||
@@ -295,7 +376,7 @@ ColumnLayout {
|
||||
onClicked: deviceController.clearActivityLog()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Rectangle {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
@@ -311,88 +392,87 @@ ColumnLayout {
|
||||
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: 12
|
||||
wrapMode: TextArea.WordWrap
|
||||
color: Theme.bodyColor
|
||||
background: null
|
||||
}
|
||||
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
|
||||
activityLog.text = newLog;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Signal Handlers ---
|
||||
Connections {
|
||||
Connections {
|
||||
target: deviceController
|
||||
|
||||
function onLogMessage(message) {
|
||||
if (message == "CHOOSE_SAVE_DIR"){
|
||||
saveDirDialog.open()
|
||||
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
|
||||
}
|
||||
|
||||
// Any operation start (detect/read/erase/debug) latches the panel on.
|
||||
function onPortsUpdated() {
|
||||
// Status tab always visible now
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
// On failure, keep the last displayed wafer info and do not change waferDetected.
|
||||
}
|
||||
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);
|
||||
}
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: deviceController
|
||||
function onReadResult(result) {
|
||||
root.dataParsed = false
|
||||
root.dataRows = 0
|
||||
root.dataCols = 0
|
||||
root.csvPath = ""
|
||||
root.dataParsed = false;
|
||||
root.dataRows = 0;
|
||||
root.dataCols = 0;
|
||||
root.csvPath = "";
|
||||
|
||||
if (result && result.success === true)
|
||||
saveDirDialog.open()
|
||||
saveDirDialog.open();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,12 +480,12 @@ ColumnLayout {
|
||||
target: deviceController
|
||||
function onParsedDataReady(result) {
|
||||
if (result && result.success) {
|
||||
root.dataParsed = true
|
||||
root.dataRows = result.rows
|
||||
root.dataCols = result.cols
|
||||
root.csvPath = result.csv_path || ""
|
||||
root.dataParsed = true;
|
||||
root.dataRows = result.rows;
|
||||
root.dataCols = result.cols;
|
||||
root.csvPath = result.csv_path || "";
|
||||
} else {
|
||||
root.dataParsed = false
|
||||
root.dataParsed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user