Refactor main application entry and enhance UI with file browser integration

- Changed application entry point to use QApplication for better compatibility with widgets.
- Set up QML UI style to support custom button backgrounds.
- Introduced LocalSettingsModel and FileBrowser for managing application settings and file selection.
- Updated QML components to reflect new data models and improve layout consistency.
- Enhanced Theme.qml with detailed comments and improved color management for better readability.
This commit is contained in:
Jack.Le
2026-04-27 14:28:08 -07:00
parent 9f8c6e1a4c
commit fbb04eb2f7
6 changed files with 466 additions and 101 deletions
+106 -45
View File
@@ -41,7 +41,8 @@ Dialog {
}
function applyMetadataFromEditor() {
if (metadataEditRow < 0) return;
if (metadataEditRow < 0)
return;
const rec = tableModel[metadataEditRow];
if (!rec) {
metadataEditDialog.close();
@@ -56,14 +57,14 @@ Dialog {
readonly property var normalizedRows: (tableModel || []).map(function (row) {
row = row || {};
return {
select: row.selected ?? false,
wafer: row.wafer ?? "",
date: row.date ?? "",
chamber: row.chamber ?? "",
edit: "",
save: "",
notes: row.notes ?? "",
fileName: row.fileName ?? "",
select: row.selected ?? false,
wafer: row.wafer ?? "",
date: row.date ?? "",
chamber: row.chamber ?? "",
edit: "",
save: "",
notes: row.notes ?? "",
fileName: row.fileName ?? "",
highlight: row.highlight ?? false
};
})
@@ -76,9 +77,7 @@ Dialog {
background: Rectangle {
radius: Theme.radiusSm
color: dialogButton.down ? Theme.buttonNeutralPressed
: dialogButton.hovered ? Theme.buttonNeutralHover
: Theme.buttonNeutralBackground
color: dialogButton.down ? Theme.buttonNeutralPressed : dialogButton.hovered ? Theme.buttonNeutralHover : Theme.buttonNeutralBackground
border.width: Theme.borderThin
border.color: Theme.fieldBorder
}
@@ -236,8 +235,17 @@ Dialog {
columnWidthProvider: function (col) {
// [select, wafer, date, chamber, notes, file (variable), edit, save]
const fixed = { 0: 40, 1: 90, 2: 170, 3: 120, 4: 180, 6: 56, 7: 56 };
if (fixed.hasOwnProperty(col)) return fixed[col];
const fixed = {
0: 40,
1: 90,
2: 170,
3: 120,
4: 180,
6: 56,
7: 56
};
if (fixed.hasOwnProperty(col))
return fixed[col];
// col 5 (File) takes remaining width
const w = Math.max(400, tableView.width);
const used = 40 + 90 + 170 + 120 + 180 + 56 + 56;
@@ -245,14 +253,30 @@ Dialog {
}
model: TableModel {
TableModelColumn { display: "select" }
TableModelColumn { display: "wafer" }
TableModelColumn { display: "date" }
TableModelColumn { display: "chamber" }
TableModelColumn { display: "notes" }
TableModelColumn { display: "fileName" }
TableModelColumn { display: "edit" }
TableModelColumn { display: "save" }
TableModelColumn {
display: "select"
}
TableModelColumn {
display: "wafer"
}
TableModelColumn {
display: "date"
}
TableModelColumn {
display: "chamber"
}
TableModelColumn {
display: "notes"
}
TableModelColumn {
display: "fileName"
}
TableModelColumn {
display: "edit"
}
TableModelColumn {
display: "save"
}
rows: root.normalizedRows
}
@@ -265,8 +289,10 @@ Dialog {
border.color: Theme.softBorder
border.width: Theme.borderThin
color: {
if (root.selectedRow === row) return Theme.sideActiveBackground;
if (root.tableModel[row]?.highlight) return Theme.subtleSectionBackground;
if (root.selectedRow === row)
return Theme.sideActiveBackground;
if (root.tableModel[row]?.highlight)
return Theme.subtleSectionBackground;
return row % 2 === 0 ? Theme.cardBackground : Theme.tone100;
}
@@ -297,9 +323,7 @@ Dialog {
background: Rectangle {
radius: Theme.radiusXs
color: parent.down ? Theme.buttonNeutralPressed
: parent.hovered ? Theme.buttonNeutralHover
: Theme.buttonNeutralBackground
color: parent.down ? Theme.buttonNeutralPressed : parent.hovered ? Theme.buttonNeutralHover : Theme.buttonNeutralBackground
border.width: Theme.borderThin
border.color: Theme.fieldBorder
}
@@ -325,15 +349,14 @@ Dialog {
font.pixelSize: 12
onClicked: {
const record = root.tableModel[row];
if (!record) return;
if (!record)
return;
file_browser.saveMetadata(record.fileName ?? "", record.wafer ?? "", record.date ?? "", record.chamber ?? "", record.notes ?? "", record.selected ?? false);
}
background: Rectangle {
radius: Theme.radiusXs
color: parent.down ? Theme.buttonNeutralPressed
: parent.hovered ? Theme.buttonNeutralHover
: Theme.buttonNeutralBackground
color: parent.down ? Theme.buttonNeutralPressed : parent.hovered ? Theme.buttonNeutralHover : Theme.buttonNeutralBackground
border.width: Theme.borderThin
border.color: Theme.fieldBorder
}
@@ -359,9 +382,12 @@ Dialog {
verticalAlignment: Text.AlignVCenter
text: {
const record = root.tableModel[row] || {};
if (column === 1) return record.wafer ?? "";
if (column === 2) return record.date ?? "";
if (column === 5) return record.fileName ?? "";
if (column === 1)
return record.wafer ?? "";
if (column === 2)
return record.date ?? "";
if (column === 5)
return record.fileName ?? "";
return "";
}
elide: Text.ElideRight
@@ -381,7 +407,8 @@ Dialog {
verticalAlignment: Text.AlignVCenter
text: {
const record = root.tableModel[row] || {};
if (column === 3) return record.chamber ?? "";
if (column === 3)
return record.chamber ?? "";
return record.notes ?? "";
}
elide: Text.ElideRight
@@ -496,7 +523,11 @@ Dialog {
anchors.fill: parent
spacing: Theme.settingsGridSpacing
Label { text: qsTr("File"); font.bold: true; color: Theme.headingColor }
Label {
text: qsTr("File")
font.bold: true
color: Theme.headingColor
}
Text {
id: filePathLabel
@@ -509,17 +540,45 @@ Dialog {
font.pixelSize: 12
}
Label { text: qsTr("Wafer"); color: Theme.headingColor }
DialogTextInput { id: waferField; Layout.fillWidth: true; Layout.preferredHeight: 36 }
Label {
text: qsTr("Wafer")
color: Theme.headingColor
}
DialogTextInput {
id: waferField
Layout.fillWidth: true
Layout.preferredHeight: 36
}
Label { text: qsTr("Date"); color: Theme.headingColor }
DialogTextInput { id: dateField; Layout.fillWidth: true; Layout.preferredHeight: 36 }
Label {
text: qsTr("Date")
color: Theme.headingColor
}
DialogTextInput {
id: dateField
Layout.fillWidth: true
Layout.preferredHeight: 36
}
Label { text: qsTr("Chamber"); color: Theme.headingColor }
DialogTextInput { id: chamberField; Layout.fillWidth: true; Layout.preferredHeight: 36 }
Label {
text: qsTr("Chamber")
color: Theme.headingColor
}
DialogTextInput {
id: chamberField
Layout.fillWidth: true
Layout.preferredHeight: 36
}
Label { text: qsTr("Notes"); color: Theme.headingColor }
DialogTextInput { id: notesField; Layout.fillWidth: true; Layout.preferredHeight: 36 }
Label {
text: qsTr("Notes")
color: Theme.headingColor
}
DialogTextInput {
id: notesField
Layout.fillWidth: true
Layout.preferredHeight: 36
}
CheckBox {
id: selectedField
@@ -531,7 +590,9 @@ Dialog {
Layout.topMargin: 8
spacing: 8
Item { Layout.fillWidth: true }
Item {
Layout.fillWidth: true
}
DialogActionButton {
text: qsTr("Cancel")