240 lines
8.9 KiB
QML
240 lines
8.9 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
import ISC
|
|
|
|
Dialog {
|
|
id: root
|
|
title: "Sensor Override"
|
|
modal: true
|
|
standardButtons: Dialog.NoButton
|
|
width: 300
|
|
|
|
// Anchor to the top-left of the window instead of the default centered position.
|
|
x: 24
|
|
y: 24
|
|
|
|
// called by WaferMapView's TapHandler
|
|
property int sensorIndex: -1
|
|
property string sensorLabel: ""
|
|
property real currentValue: 0.0
|
|
property bool hasOverride: streamController.overriddenSensors.indexOf(sensorIndex) >= 0
|
|
|
|
function openFor(index) {
|
|
sensorIndex = index;
|
|
var dot = streamController.sensorDots[index];
|
|
if (!dot)
|
|
return;
|
|
sensorLabel = dot.label !== undefined ? String(dot.label) : String(index + 1);
|
|
currentValue = dot.value;
|
|
valueField.text = "";
|
|
offsetField.text = "";
|
|
open();
|
|
}
|
|
|
|
background: Rectangle {
|
|
color: Theme.cardBackground
|
|
radius: Theme.radiusLg
|
|
border.color: Theme.cardBorder
|
|
border.width: Theme.borderThin
|
|
}
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
spacing: Theme.rightPaneGap
|
|
|
|
// ── header ───────────────────────────────────────────────
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
Label {
|
|
text: "Sensor #" + (root.sensorIndex + 1) + (root.sensorLabel ? " (" + root.sensorLabel + ")" : "")
|
|
color: Theme.headingColor
|
|
font.bold: true
|
|
font.pixelSize: Theme.fontSm
|
|
Layout.fillWidth: true
|
|
}
|
|
Rectangle {
|
|
visible: root.hasOverride
|
|
width: overrideTag.implicitWidth + 12
|
|
height: overrideTag.implicitHeight + 6
|
|
radius: 4
|
|
color: Theme.statusWarningColor
|
|
opacity: 0.85
|
|
Label {
|
|
id: overrideTag
|
|
anchors.centerIn: parent
|
|
text: "OVERRIDE"
|
|
color: Theme.statusBadgeText
|
|
font.pixelSize: Theme.fontXs
|
|
font.bold: true
|
|
font.letterSpacing: 1
|
|
}
|
|
}
|
|
}
|
|
|
|
Label {
|
|
text: "Live: " + root.currentValue.toFixed(2)
|
|
color: Theme.bodyColor
|
|
font.pixelSize: Theme.fontSm
|
|
}
|
|
|
|
Rectangle {
|
|
Layout.fillWidth: true
|
|
height: 1
|
|
color: Theme.cardBorder
|
|
}
|
|
|
|
// ── replace field ─────────────────────────────────────────
|
|
Label {
|
|
text: "Replace with value"
|
|
color: Theme.bodyColor
|
|
font.pixelSize: Theme.fontXs
|
|
}
|
|
TextField {
|
|
id: valueField
|
|
Layout.fillWidth: true
|
|
placeholderText: "100"
|
|
inputMethodHints: Qt.ImhFormattedNumbersOnly
|
|
color: Theme.fieldText
|
|
placeholderTextColor: Theme.fieldPlaceholder
|
|
selectedTextColor: Theme.fieldBackground
|
|
selectionColor: Theme.fieldText
|
|
background: Rectangle {
|
|
radius: Theme.radiusXs
|
|
color: Theme.fieldBackground
|
|
border.width: valueField.activeFocus ? Theme.borderStrong : Theme.borderThin
|
|
border.color: valueField.activeFocus ? Theme.fieldBorderFocus : Theme.fieldBorder
|
|
Behavior on color {
|
|
ColorAnimation { duration: Theme.durationFast }
|
|
}
|
|
Behavior on border.color {
|
|
ColorAnimation { duration: Theme.durationFast }
|
|
}
|
|
}
|
|
}
|
|
|
|
// ── offset field ──────────────────────────────────────────
|
|
Label {
|
|
text: "Or add offset (± delta)"
|
|
color: Theme.bodyColor
|
|
font.pixelSize: Theme.fontXs
|
|
}
|
|
TextField {
|
|
id: offsetField
|
|
Layout.fillWidth: true
|
|
placeholderText: "e.g. +0.5 or -0.5 (blank = skip)"
|
|
inputMethodHints: Qt.ImhFormattedNumbersOnly
|
|
color: Theme.fieldText
|
|
placeholderTextColor: Theme.fieldPlaceholder
|
|
selectedTextColor: Theme.fieldBackground
|
|
selectionColor: Theme.fieldText
|
|
background: Rectangle {
|
|
radius: Theme.radiusXs
|
|
color: Theme.fieldBackground
|
|
border.width: offsetField.activeFocus ? Theme.borderStrong : Theme.borderThin
|
|
border.color: offsetField.activeFocus ? Theme.fieldBorderFocus : Theme.fieldBorder
|
|
Behavior on color {
|
|
ColorAnimation { duration: Theme.durationFast }
|
|
}
|
|
Behavior on border.color {
|
|
ColorAnimation { duration: Theme.durationFast }
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
Layout.fillWidth: true
|
|
height: 1
|
|
color: Theme.cardBorder
|
|
}
|
|
|
|
// ── buttons ───────────────────────────────────────────────
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: 8
|
|
|
|
Button {
|
|
id: applyBtn
|
|
text: "Apply"
|
|
Layout.fillWidth: true
|
|
hoverEnabled: true
|
|
enabled: valueField.text !== "" || offsetField.text !== ""
|
|
opacity: enabled ? 1.0 : 0.4
|
|
background: Rectangle {
|
|
radius: Theme.radiusSm
|
|
color: applyBtn.down ? Theme.buttonNeutralPressed : applyBtn.hovered ? Theme.buttonNeutralHover : Theme.buttonNeutralBackground
|
|
border.width: Theme.borderThin
|
|
border.color: Theme.fieldBorder
|
|
}
|
|
contentItem: Text {
|
|
text: applyBtn.text
|
|
color: Theme.buttonNeutralText
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
font.bold: true
|
|
font.pixelSize: Theme.fontSm
|
|
}
|
|
onClicked: {
|
|
if (valueField.text !== "") {
|
|
var v = parseFloat(valueField.text);
|
|
if (!isNaN(v))
|
|
streamController.replaceSensor(root.sensorIndex, v);
|
|
}
|
|
if (offsetField.text !== "") {
|
|
var d = parseFloat(offsetField.text);
|
|
if (!isNaN(d))
|
|
streamController.offsetSensor(root.sensorIndex, d);
|
|
}
|
|
root.close();
|
|
}
|
|
}
|
|
Button {
|
|
id: clearBtn
|
|
text: "Clear"
|
|
Layout.fillWidth: true
|
|
hoverEnabled: true
|
|
enabled: root.hasOverride
|
|
opacity: enabled ? 1.0 : 0.4
|
|
background: Rectangle {
|
|
radius: Theme.radiusSm
|
|
color: clearBtn.down ? Theme.buttonNeutralPressed : clearBtn.hovered ? Theme.buttonNeutralHover : Theme.buttonNeutralBackground
|
|
border.width: Theme.borderThin
|
|
border.color: Theme.fieldBorder
|
|
}
|
|
contentItem: Text {
|
|
text: clearBtn.text
|
|
color: Theme.buttonNeutralText
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
font.bold: true
|
|
font.pixelSize: Theme.fontSm
|
|
}
|
|
onClicked: {
|
|
streamController.clearSensorEdit(root.sensorIndex);
|
|
root.close();
|
|
}
|
|
}
|
|
Button {
|
|
id: cancelBtn
|
|
text: "Cancel"
|
|
hoverEnabled: true
|
|
background: Rectangle {
|
|
radius: Theme.radiusSm
|
|
color: cancelBtn.down ? Theme.buttonNeutralPressed : cancelBtn.hovered ? Theme.buttonNeutralHover : Theme.buttonNeutralBackground
|
|
border.width: Theme.borderThin
|
|
border.color: Theme.fieldBorder
|
|
}
|
|
contentItem: Text {
|
|
text: cancelBtn.text
|
|
color: Theme.buttonNeutralText
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
font.bold: true
|
|
font.pixelSize: Theme.fontSm
|
|
}
|
|
onClicked: root.close()
|
|
}
|
|
}
|
|
}
|
|
}
|