feat(ui): refine AboutDialog layout and add nav pill tooltips
This commit is contained in:
@@ -9,8 +9,8 @@ Popup {
|
|||||||
modal: true
|
modal: true
|
||||||
dim: true
|
dim: true
|
||||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||||
width: 480
|
width: 600
|
||||||
height: 440
|
height: 500
|
||||||
anchors.centerIn: Overlay.overlay
|
anchors.centerIn: Overlay.overlay
|
||||||
|
|
||||||
onOpened: licenseModel.refresh()
|
onOpened: licenseModel.refresh()
|
||||||
@@ -31,8 +31,8 @@ Popup {
|
|||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 24
|
anchors.margins: 28
|
||||||
spacing: 16
|
spacing: 20
|
||||||
|
|
||||||
// ── Title ──
|
// ── Title ──
|
||||||
Label {
|
Label {
|
||||||
@@ -44,27 +44,20 @@ Popup {
|
|||||||
|
|
||||||
// ── App info ──
|
// ── App info ──
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 4
|
spacing: 6
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: "ISenseCloud (ISC)"
|
text: "ISenseCloud"
|
||||||
font.pixelSize: Theme.fontLg
|
font.pixelSize: Theme.fontXl
|
||||||
|
font.bold: true
|
||||||
color: Theme.headingColor
|
color: Theme.headingColor
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: "Version " + appVersion
|
text: "Version " + appVersion
|
||||||
font.pixelSize: Theme.fontSm
|
font.pixelSize: Theme.fontMd
|
||||||
color: Theme.bodyColor
|
color: Theme.bodyColor
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
|
||||||
text: "Temperature-sensing wafer monitoring"
|
|
||||||
font.pixelSize: Theme.fontSm
|
|
||||||
color: Theme.bodyColor
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Separator ──
|
// ── Separator ──
|
||||||
@@ -78,7 +71,7 @@ Popup {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.minimumHeight: 120
|
Layout.minimumHeight: 150
|
||||||
radius: Theme.radiusSm
|
radius: Theme.radiusSm
|
||||||
color: Theme.panelBackground
|
color: Theme.panelBackground
|
||||||
border.color: Theme.cardBorder
|
border.color: Theme.cardBorder
|
||||||
@@ -86,8 +79,8 @@ Popup {
|
|||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 10
|
anchors.margins: 14
|
||||||
spacing: 2
|
spacing: 6
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -95,7 +88,8 @@ Popup {
|
|||||||
Label {
|
Label {
|
||||||
text: "LICENSE"
|
text: "LICENSE"
|
||||||
color: Theme.panelTitleText
|
color: Theme.panelTitleText
|
||||||
font.pixelSize: Theme.fontXs
|
font.pixelSize: Theme.fontSm
|
||||||
|
font.bold: true
|
||||||
font.letterSpacing: 0.5
|
font.letterSpacing: 0.5
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
@@ -105,18 +99,18 @@ Popup {
|
|||||||
visible: false
|
visible: false
|
||||||
text: "Invalid license file"
|
text: "Invalid license file"
|
||||||
color: Theme.statusWarningColor
|
color: Theme.statusWarningColor
|
||||||
font.pixelSize: Theme.fontXs
|
font.pixelSize: Theme.fontSm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grid header
|
// Grid header
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: 4
|
spacing: 8
|
||||||
Label { text: "Wafer SN"; font.pixelSize: Theme.fontXs; font.bold: true; color: Theme.subheadingColor; Layout.preferredWidth: 100 }
|
Label { text: "Wafer SN"; font.pixelSize: Theme.fontSm; font.bold: true; color: Theme.subheadingColor; Layout.preferredWidth: 150 }
|
||||||
Label { text: "Mfg Date"; font.pixelSize: Theme.fontXs; font.bold: true; color: Theme.subheadingColor; Layout.preferredWidth: 90 }
|
Label { text: "Mfg Date"; font.pixelSize: Theme.fontSm; font.bold: true; color: Theme.subheadingColor; Layout.preferredWidth: 120 }
|
||||||
Label { text: "Level"; font.pixelSize: Theme.fontXs; font.bold: true; color: Theme.subheadingColor; Layout.preferredWidth: 50 }
|
Label { text: "Level"; font.pixelSize: Theme.fontSm; font.bold: true; color: Theme.subheadingColor; Layout.preferredWidth: 80 }
|
||||||
Label { text: "License Date"; font.pixelSize: Theme.fontXs; font.bold: true; color: Theme.subheadingColor; Layout.fillWidth: true }
|
Label { text: "License Date"; font.pixelSize: Theme.fontSm; font.bold: true; color: Theme.subheadingColor; Layout.fillWidth: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -133,11 +127,11 @@ Popup {
|
|||||||
model: licenseModel.licenses
|
model: licenseModel.licenses
|
||||||
delegate: RowLayout {
|
delegate: RowLayout {
|
||||||
width: ListView.view.width
|
width: ListView.view.width
|
||||||
spacing: 4
|
spacing: 8
|
||||||
Label { text: modelData.serial; font.pixelSize: Theme.fontSm; color: Theme.bodyColor; Layout.preferredWidth: 100 }
|
Label { text: modelData.serial; font.pixelSize: Theme.fontMd; color: Theme.bodyColor; Layout.preferredWidth: 150 }
|
||||||
Label { text: modelData.mfgDate; font.pixelSize: Theme.fontSm; color: Theme.bodyColor; Layout.preferredWidth: 90 }
|
Label { text: modelData.mfgDate; font.pixelSize: Theme.fontMd; color: Theme.bodyColor; Layout.preferredWidth: 120 }
|
||||||
Label { text: modelData.level; font.pixelSize: Theme.fontSm; color: Theme.bodyColor; Layout.preferredWidth: 50 }
|
Label { text: modelData.level; font.pixelSize: Theme.fontMd; color: Theme.bodyColor; Layout.preferredWidth: 80 }
|
||||||
Label { text: modelData.licDate; font.pixelSize: Theme.fontSm; color: Theme.bodyColor; Layout.fillWidth: true }
|
Label { text: modelData.licDate; font.pixelSize: Theme.fontMd; color: Theme.bodyColor; Layout.fillWidth: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +139,7 @@ Popup {
|
|||||||
visible: licenseModel.licenses.length === 0
|
visible: licenseModel.licenses.length === 0
|
||||||
text: "No license loaded"
|
text: "No license loaded"
|
||||||
color: Theme.bodyColor
|
color: Theme.bodyColor
|
||||||
font.pixelSize: Theme.fontSm
|
font.pixelSize: Theme.fontMd
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
@@ -157,11 +151,12 @@ Popup {
|
|||||||
// ── Buttons ──
|
// ── Buttons ──
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
spacing: 12
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
text: "Load License"
|
text: "Load License"
|
||||||
Layout.preferredWidth: 120
|
Layout.preferredWidth: 140
|
||||||
Layout.preferredHeight: 32
|
Layout.preferredHeight: 36
|
||||||
onClicked: licenseFileDialog.open()
|
onClicked: licenseFileDialog.open()
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
@@ -173,6 +168,8 @@ Popup {
|
|||||||
contentItem: Label {
|
contentItem: Label {
|
||||||
text: parent.text
|
text: parent.text
|
||||||
color: Theme.buttonNeutralText
|
color: Theme.buttonNeutralText
|
||||||
|
font.pixelSize: Theme.fontMd
|
||||||
|
font.bold: true
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
}
|
}
|
||||||
@@ -183,7 +180,7 @@ Popup {
|
|||||||
Button {
|
Button {
|
||||||
text: "Close"
|
text: "Close"
|
||||||
Layout.preferredWidth: 100
|
Layout.preferredWidth: 100
|
||||||
Layout.preferredHeight: 32
|
Layout.preferredHeight: 36
|
||||||
onClicked: root.close()
|
onClicked: root.close()
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
@@ -195,6 +192,8 @@ Popup {
|
|||||||
contentItem: Label {
|
contentItem: Label {
|
||||||
text: parent.text
|
text: parent.text
|
||||||
color: Theme.buttonNeutralText
|
color: Theme.buttonNeutralText
|
||||||
|
font.pixelSize: Theme.fontMd
|
||||||
|
font.bold: true
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-12
@@ -26,6 +26,8 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
property bool memoryRead: false
|
property bool memoryRead: false
|
||||||
property bool waferDetected: false
|
property bool waferDetected: false
|
||||||
// TODO P2.2: add `property bool waferLicensed: false`; set it in
|
// TODO P2.2: add `property bool waferLicensed: false`; set it in
|
||||||
@@ -213,9 +215,24 @@ Rectangle {
|
|||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
id: pillModel
|
id: pillModel
|
||||||
ListElement { label: "STATUS"; icon: "Tabs/icons/status.svg"; expandW: 86 }
|
ListElement {
|
||||||
ListElement { label: "DATA"; icon: "Tabs/icons/data.svg"; expandW: 66 }
|
label: "STATUS"
|
||||||
ListElement { label: "MAP"; icon: "Tabs/icons/map.svg"; expandW: 58 }
|
icon: "Tabs/icons/status.svg"
|
||||||
|
expandW: 86
|
||||||
|
desc: "Monitor real-time device connection, serial communication, and execute wafer actions."
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
label: "DATA"
|
||||||
|
icon: "Tabs/icons/data.svg"
|
||||||
|
expandW: 66
|
||||||
|
desc: "Manage, review, compare (DTW), and split historical sensor data records."
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
label: "MAP"
|
||||||
|
icon: "Tabs/icons/map.svg"
|
||||||
|
expandW: 58
|
||||||
|
desc: "Visualize spatial sensor readings on a 2D thin-plate spline RBF interpolated heatmap."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
@@ -227,15 +244,6 @@ Rectangle {
|
|||||||
model: pillModel
|
model: pillModel
|
||||||
delegate: Button {
|
delegate: Button {
|
||||||
id: pillBtn
|
id: pillBtn
|
||||||
// TODO P3.1: lock MAP pill (index 2) when no license:
|
|
||||||
// `enabled: index !== 2 || licenseModel.licenses.length > 0`
|
|
||||||
// and dim icon/label when disabled. licensesChanged
|
|
||||||
// notify already fires on Load License → unlocks live,
|
|
||||||
// no restart. Rule is "any valid license" (not
|
|
||||||
// per-wafer): Map also replays CSVs with no wafer
|
|
||||||
// attached. Also gate the Map Loader (see TODO at the
|
|
||||||
// StackLayout below) and the auto-switch at
|
|
||||||
// onParsedDataReady. See plan §3.1.
|
|
||||||
checked: root.selectedTabIndex === index
|
checked: root.selectedTabIndex === index
|
||||||
flat: true
|
flat: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -305,6 +313,11 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppToolTip {
|
||||||
|
visible: pillBtn.hovered
|
||||||
|
text: "<b>" + model.label + "</b>: " + model.desc
|
||||||
|
}
|
||||||
|
|
||||||
onClicked: root.selectedTabIndex = index
|
onClicked: root.selectedTabIndex = index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -598,6 +611,8 @@ Rectangle {
|
|||||||
UtilityFooter {
|
UtilityFooter {
|
||||||
id: utilFooter
|
id: utilFooter
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
settingsPopup: settingsPopup
|
||||||
|
aboutDialog: aboutDialog
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user