OptionsPopup: Qt6 rework

Relayout the OptionsPopup - introduce wider use of anchors
rather than calculated values, nest controls as is appropriate for
their rendering.

Additionally, right-align all the textfields, and make the uniform size,
offset the labels to indicate shared context, and numerous layout
simplifications.

Finally - make behaviours dependent on the value of a checkbox actually
depend on that checkbox - rather than some sort of 'enabled' flag on a
layout.
This commit is contained in:
Tom Dewey 2024-07-17 10:18:34 +01:00 committed by Tom Dewey
parent 0743797996
commit 9b14f88ba6

View file

@ -48,7 +48,8 @@ Window {
//Layout.maximumWidth: popup.width-30 //Layout.maximumWidth: popup.width-30
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
Layout.leftMargin: 25 Layout.leftMargin: 10
Layout.rightMargin: 10
Layout.topMargin: 10 Layout.topMargin: 10
clip: true clip: true
//ScrollBar.vertical.policy: ScrollBar.AlwaysOn //ScrollBar.vertical.policy: ScrollBar.AlwaysOn
@ -81,7 +82,6 @@ Window {
ColumnLayout { ColumnLayout {
// General tab // General tab
spacing: -10
RowLayout { RowLayout {
ImCheckBox { ImCheckBox {
@ -93,6 +93,10 @@ Window {
} }
} }
} }
// Spacer item
Item {
Layout.fillWidth: true
}
TextField { TextField {
id: fieldHostname id: fieldHostname
enabled: chkHostname.checked enabled: chkHostname.checked
@ -100,6 +104,7 @@ Window {
selectByMouse: true selectByMouse: true
maximumLength: 253 maximumLength: 253
validator: RegularExpressionValidator { regularExpression: /[0-9A-Za-z][0-9A-Za-z-]{0,62}/ } validator: RegularExpressionValidator { regularExpression: /[0-9A-Za-z][0-9A-Za-z-]{0,62}/ }
Layout.minimumWidth: 200
} }
Text { Text {
text : ".local" text : ".local"
@ -120,66 +125,69 @@ Window {
} }
} }
ColumnLayout { RowLayout {
enabled: chkSetUser.checked Text {
Layout.leftMargin: 40 text: qsTr("Username:")
spacing: -5 color: parent.enabled ? (fieldUserName.indicateError ? "red" : "black") : "grey"
Layout.leftMargin: 40
}
// Spacer item
Item {
Layout.fillWidth: true
}
TextField {
id: fieldUserName
enabled: chkSetUser.checked
text: "pi"
Layout.minimumWidth: 200
selectByMouse: true
property bool indicateError: false
maximumLength: 31
validator: RegularExpressionValidator { regularExpression: /^[a-z][a-z0-9-]{0,30}$/ }
GridLayout { onTextEdited: {
columns: 2 indicateError = false
columnSpacing: 10
rowSpacing: -5
Text {
text: qsTr("Username:")
color: parent.enabled ? (fieldUserName.indicateError ? "red" : "black") : "grey"
} }
TextField { }
id: fieldUserName }
text: "pi" RowLayout {
Layout.minimumWidth: 200 Text {
selectByMouse: true text: qsTr("Password:")
property bool indicateError: false color: parent.enabled ? (fieldUserPassword.indicateError ? "red" : "black") : "grey"
maximumLength: 31 Layout.leftMargin: 40
validator: RegularExpressionValidator { regularExpression: /^[a-z][a-z0-9-]{0,30}$/ } }
// Spacer item
Item {
Layout.fillWidth: true
}
TextField {
id: fieldUserPassword
enabled: chkSetUser.checked
echoMode: TextInput.Password
passwordMaskDelay: 2000 //ms
Layout.minimumWidth: 200
selectByMouse: true
property bool alreadyCrypted: false
property bool indicateError: false
onTextEdited: { Keys.onPressed: (event)=> {
if (alreadyCrypted) {
/* User is trying to edit saved
(crypted) password, clear field */
alreadyCrypted = false
clear()
}
// Do not mark the event as accepted, so that it may
// propagate down to the underlying TextField.
event.accepted = false
}
onTextEdited: {
if (indicateError) {
indicateError = false indicateError = false
} }
} }
Text {
text: qsTr("Password:")
color: parent.enabled ? (fieldUserPassword.indicateError ? "red" : "black") : "grey"
}
TextField {
id: fieldUserPassword
echoMode: TextInput.Password
passwordMaskDelay: 2000 //ms
Layout.minimumWidth: 200
selectByMouse: true
property bool alreadyCrypted: false
property bool indicateError: false
Keys.onPressed: (event)=> {
if (alreadyCrypted) {
/* User is trying to edit saved
(crypted) password, clear field */
alreadyCrypted = false
clear()
}
// Do not mark the event as accepted, so that it may
// propagate down to the underlying TextField.
event.accepted = false
}
onTextEdited: {
if (indicateError) {
indicateError = false
}
}
}
} }
} }
@ -196,19 +204,21 @@ Window {
} }
} }
} }
GridLayout {
enabled: chkWifi.checked
Layout.leftMargin: 40
columns: 2
columnSpacing: 10
rowSpacing: -5
RowLayout {
Text { Text {
text: qsTr("SSID:") text: qsTr("SSID:")
color: parent.enabled ? (fieldWifiSSID.indicateError ? "red" : "black") : "grey" color: chkWifi.checked ? (fieldWifiSSID.indicateError ? "red" : "black") : "grey"
Layout.leftMargin: 40
}
// Spacer item
Item {
Layout.fillWidth: true
} }
TextField { TextField {
id: fieldWifiSSID id: fieldWifiSSID
// placeholderText: qsTr("SSID")
enabled: chkWifi.checked
Layout.minimumWidth: 200 Layout.minimumWidth: 200
selectByMouse: true selectByMouse: true
property bool indicateError: false property bool indicateError: false
@ -216,13 +226,20 @@ Window {
indicateError = false indicateError = false
} }
} }
}
RowLayout {
Text { Text {
text: qsTr("Password:") text: qsTr("Password:")
color: parent.enabled ? (fieldWifiPassword.indicateError ? "red" : "black") : "grey" color: chkWifi.checked ? (fieldWifiPassword.indicateError ? "red" : "black") : "grey"
Layout.leftMargin: 40
}
// Spacer item
Item {
Layout.fillWidth: true
} }
TextField { TextField {
id: fieldWifiPassword id: fieldWifiPassword
enabled: chkWifi.checked
Layout.minimumWidth: 200 Layout.minimumWidth: 200
selectByMouse: true selectByMouse: true
echoMode: chkShowPassword.checked ? TextInput.Normal : TextInput.Password echoMode: chkShowPassword.checked ? TextInput.Normal : TextInput.Password
@ -231,29 +248,48 @@ Window {
indicateError = false indicateError = false
} }
} }
}
RowLayout { RowLayout {
Layout.columnSpan: 2 // Spacer item
Item {
ImCheckBox { Layout.fillWidth: true
id: chkShowPassword
text: qsTr("Show password")
checked: true
}
ImCheckBox {
id: chkWifiSSIDHidden
Layout.columnSpan: 2
text: qsTr("Hidden SSID")
checked: false
}
} }
ImCheckBox {
id: chkShowPassword
enabled: chkWifi.checked
text: qsTr("Show password")
checked: true
}
// Spacer item
Item {
Layout.fillWidth: true
}
ImCheckBox {
id: chkWifiSSIDHidden
enabled: chkWifi.checked
Layout.columnSpan: 2
text: qsTr("Hidden SSID")
checked: false
}
// Spacer item
Item {
Layout.fillWidth: true
}
}
RowLayout {
Text { Text {
text: qsTr("Wireless LAN country:") text: qsTr("Wireless LAN country:")
color: parent.enabled ? "black" : "grey" color: chkWifi.checked ? "black" : "grey"
}
// Spacer item
Item {
Layout.fillWidth: true
} }
ComboBox { ComboBox {
id: fieldWifiCountry id: fieldWifiCountry
enabled: chkWifi.checked
editable: true editable: true
} }
} }
@ -262,28 +298,36 @@ Window {
id: chkLocale id: chkLocale
text: qsTr("Set locale settings") text: qsTr("Set locale settings")
} }
GridLayout { RowLayout {
enabled: chkLocale.checked
Layout.leftMargin: 40
columns: 2
columnSpacing: 10
rowSpacing: -5
Text { Text {
text: qsTr("Time zone:") text: qsTr("Time zone:")
color: parent.enabled ? "black" : "grey" color: chkLocale.checked ? "black" : "grey"
Layout.leftMargin: 40
}
// Spacer item
Item {
Layout.fillWidth: true
} }
ComboBox { ComboBox {
enabled: chkLocale.checked
id: fieldTimezone id: fieldTimezone
editable: true editable: true
Layout.minimumWidth: 200 Layout.minimumWidth: 200
} }
}
RowLayout {
Text { Text {
text: qsTr("Keyboard layout:") text: qsTr("Keyboard layout:")
color: parent.enabled ? "black" : "grey" color: chkLocale.checked ? "black" : "grey"
Layout.leftMargin: 40
}
// Spacer item
Item {
Layout.fillWidth: true
} }
ComboBox { ComboBox {
enabled: chkLocale.checked
id: fieldKeyboardLayout id: fieldKeyboardLayout
editable: true editable: true
Layout.minimumWidth: 200 Layout.minimumWidth: 200
@ -293,7 +337,6 @@ Window {
ColumnLayout { ColumnLayout {
// Remote access tab // Remote access tab
spacing: -10
ImCheckBox { ImCheckBox {
id: chkSSH id: chkSSH
@ -309,68 +352,61 @@ Window {
} }
} }
} }
ColumnLayout {
ImRadioButton {
id: radioPasswordAuthentication
enabled: chkSSH.checked enabled: chkSSH.checked
text: qsTr("Use password authentication")
onCheckedChanged: {
if (checked) {
chkSetUser.checked = true
//fieldUserPassword.forceActiveFocus()
}
}
}
ImRadioButton {
id: radioPubKeyAuthentication
enabled: chkSSH.checked
text: qsTr("Allow public-key authentication only")
onCheckedChanged: {
if (checked) {
if (chkSetUser.checked && fieldUserName.text == "pi" && fieldUserPassword.text.length == 0) {
chkSetUser.checked = false
}
fieldPublicKey.forceActiveFocus()
}
}
}
Text {
text: qsTr("Set authorized_keys for '%1':").arg(fieldUserName.text)
color: radioPubKeyAuthentication.checked ? "black" : "grey"
textFormat: Text.PlainText
Layout.leftMargin: 40 Layout.leftMargin: 40
spacing: -10 }
TextArea {
id: fieldPublicKey
enabled: radioPubKeyAuthentication.checked
wrapMode: TextEdit.WrapAnywhere
Layout.minimumWidth: 400
Layout.leftMargin: 40
selectByMouse: true
}
ImRadioButton { ImButton {
id: radioPasswordAuthentication text: qsTr("RUN SSH-KEYGEN")
text: qsTr("Use password authentication") Layout.leftMargin: 40
onCheckedChanged: { enabled: imageWriter.hasSshKeyGen() && !imageWriter.hasPubKey()
if (checked) { onClicked: {
chkSetUser.checked = true enabled = false
//fieldUserPassword.forceActiveFocus() imageWriter.generatePubKey()
} fieldPublicKey.text = imageWriter.getDefaultPubKey()
}
}
ImRadioButton {
id: radioPubKeyAuthentication
text: qsTr("Allow public-key authentication only")
onCheckedChanged: {
if (checked) {
if (chkSetUser.checked && fieldUserName.text == "pi" && fieldUserPassword.text.length == 0) {
chkSetUser.checked = false
}
fieldPublicKey.forceActiveFocus()
}
}
}
GridLayout {
Layout.leftMargin: 40
columns: 1
columnSpacing: 10
rowSpacing: -5
enabled: radioPubKeyAuthentication.checked
Text {
text: qsTr("Set authorized_keys for '%1':").arg(fieldUserName.text)
color: parent.enabled ? "black" : "grey"
textFormat: Text.PlainText
}
TextArea {
id: fieldPublicKey
wrapMode: TextEdit.WrapAnywhere
Layout.minimumWidth: 400
selectByMouse: true
}
ImButton {
text: qsTr("RUN SSH-KEYGEN")
enabled: imageWriter.hasSshKeyGen() && !imageWriter.hasPubKey()
onClicked: {
enabled = false
imageWriter.generatePubKey()
fieldPublicKey.text = imageWriter.getDefaultPubKey()
}
}
} }
} }
} }
ColumnLayout { ColumnLayout {
// Options tab // Options tab
spacing: -10
ImCheckBox { ImCheckBox {
id: chkBeep id: chkBeep