121 lines
4.0 KiB
QML
121 lines
4.0 KiB
QML
// A row whose button takes a short piece of typed text as its argument.
|
|
//
|
|
// FieldActionRow {
|
|
// label: "Back up now"
|
|
// placeholder: "Name (optional)"
|
|
// action: "Back up"
|
|
// onSubmitted: value => SettingsBackup.save(value)
|
|
// }
|
|
//
|
|
// TextFieldRow is for a value that IS the setting -- a hostname, an account's
|
|
// real name -- and keeps showing whatever the system currently holds. This is
|
|
// for a one-shot whose argument happens to be typed: naming a backup, setting
|
|
// the clock by hand. The field holds an argument rather than a value, so the
|
|
// caller clears it once the action is away instead of leaving text sitting
|
|
// there looking like something that took effect.
|
|
|
|
import QtQuick
|
|
import qs.config
|
|
|
|
SettingRow {
|
|
id: root
|
|
|
|
property string placeholder: ""
|
|
property string action: ""
|
|
property bool enabled: true
|
|
property int fieldWidth: 150
|
|
|
|
// What is typed right now, so a caller can require it before enabling the
|
|
// button, or seed it with a sensible starting point.
|
|
property alias text: input.text
|
|
|
|
signal submitted(value: string)
|
|
|
|
function clear(): void { input.text = ""; }
|
|
|
|
function press(): void {
|
|
if (root.enabled)
|
|
root.submitted(input.text.trim());
|
|
}
|
|
|
|
controlWidth: root.fieldWidth + submitButton.implicitWidth + 10
|
|
|
|
Row {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 10
|
|
|
|
Rectangle {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: root.fieldWidth
|
|
height: 32
|
|
radius: 9
|
|
color: Theme.alpha(Theme.fg, root.enabled ? 0.06 : 0.03)
|
|
border.width: input.activeFocus ? 2 : 1
|
|
border.color: input.activeFocus
|
|
? Theme.alpha(Theme.accent, 0.55)
|
|
: Theme.alpha(Theme.fg, 0.1)
|
|
opacity: root.enabled ? 1 : 0.5
|
|
|
|
TextInput {
|
|
id: input
|
|
|
|
anchors.fill: parent
|
|
anchors.leftMargin: 11
|
|
anchors.rightMargin: 11
|
|
enabled: root.enabled
|
|
activeFocusOnTab: root.enabled
|
|
color: Theme.fg
|
|
selectionColor: Theme.alpha(Theme.accent, 0.5)
|
|
selectedTextColor: Theme.fg
|
|
font.family: Theme.fontFamily
|
|
font.pixelSize: Theme.fontSize
|
|
verticalAlignment: TextInput.AlignVCenter
|
|
clip: true
|
|
|
|
Accessible.role: Accessible.EditableText
|
|
Accessible.name: root.label
|
|
Accessible.description: root.placeholder
|
|
|
|
// Enter in the field is the same press as the button. Typing a
|
|
// name and hitting return is what everybody does first.
|
|
onAccepted: root.press()
|
|
|
|
Text {
|
|
anchors.fill: parent
|
|
visible: input.text === ""
|
|
text: root.placeholder
|
|
color: Theme.fgMuted
|
|
font: input.font
|
|
verticalAlignment: Text.AlignVCenter
|
|
elide: Text.ElideRight
|
|
}
|
|
}
|
|
}
|
|
|
|
SettingsButton {
|
|
id: submitButton
|
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: root.action
|
|
enabled: root.enabled
|
|
activeFocusOnTab: root.enabled
|
|
border.width: activeFocus ? 2 : 1
|
|
border.color: activeFocus ? Theme.accent : Theme.alpha(Theme.fg, 0.08)
|
|
onClicked: root.press()
|
|
|
|
Accessible.role: Accessible.Button
|
|
Accessible.name: root.label
|
|
Accessible.description: root.detail === ""
|
|
? root.action
|
|
: `${root.detail} — ${root.action}`
|
|
Accessible.focusable: root.enabled
|
|
Accessible.onPressAction: root.press()
|
|
|
|
Keys.onReturnPressed: root.press()
|
|
Keys.onEnterPressed: root.press()
|
|
Keys.onSpacePressed: root.press()
|
|
}
|
|
}
|
|
}
|