DPS_Manage/DelegateUI/Controls/DelOTPInput.qml

159 lines
5.0 KiB
QML

import QtQuick 2.15
import DelegateUI 1.0
Item {
id: control
width: __row.width
height: __row.height
signal finished(input: string)
property bool animationEnabled: DelTheme.animationEnabled
property int length: 6
property int characterLength: 1
property int currentIndex: 0
property string currentInput: ''
property int itemWidth: 45
property int itemHeight: 32
property alias itemSpacing: __row.spacing
property var itemValidator: IntValidator { top: 9; bottom: 0 }
property int itemInputMethodHints: Qt.ImhHiddenText
property bool itemPassword: false
property string itemPasswordCharacter: ''
property var formatter: (text) => text
property color colorItemText: enabled ? DelTheme.DelInput.colorText : DelTheme.DelInput.colorTextDisabled
property color colorItemBorder: enabled ? DelTheme.DelInput.colorBorder : DelTheme.DelInput.colorBorderDisabled
property color colorItemBorderActive: enabled ? DelTheme.DelInput.colorBorderHover : DelTheme.DelInput.colorBorderDisabled
property color colorItemBg: enabled ? DelTheme.DelInput.colorBg : DelTheme.DelInput.colorBgDisabled
property int radiusBg: 6
property Component dividerDelegate: Item { }
onCurrentIndexChanged: {
const item = __repeater.itemAt(currentIndex << 1);
if (item && item.index % 2 == 0)
item.item.selectThis();
}
function setInput(inputs) {
for (let i = 0; i < inputs.length; i++) {
setInputAtIndex(i, input);
}
}
function setInputAtIndex(index, input) {
const item = __repeater.itemAt(index << 1);
if (item) {
currentIndex = index;
item.item.text = formatter(input);
}
}
function getInput() {
let input = '';
for (let i = 0; i < __repeater.count; i++) {
const item = __repeater.itemAt(i);
if (item && item.index % 2 == 0) {
input += item.item.text;
}
}
return input;
}
function getInputAtIndex(index) {
const item = __repeater.itemAt(index << 1);
if (item) {
return item.item.text;
}
return '';
}
Component {
id: __inputDelegate
DelInput {
id: __rootItem
width: control.itemWidth
height: control.itemHeight
verticalAlignment: DelInput.AlignVCenter
horizontalAlignment: DelInput.AlignHCenter
enabled: control.enabled
colorText: control.colorItemText
colorBorder: active ? control.colorItemBorderActive : control.colorItemBorder
colorBg: control.colorItemBg
radiusBg: control.radiusBg
validator: control.itemValidator
inputMethodHints: control.itemInputMethodHints
echoMode: control.itemPassword ? DelInput.Password : DelInput.Normal
passwordCharacter:control.itemPasswordCharacter
onReleased: __timer.restart();
onTextEdited: {
text = control.formatter(text);
const isFull = length >= control.characterLength;
if (isFull) selectAll();
if (isBackspace) isBackspace = false;
const input = control.getInput();
control.currentInput = input;
if (isFull) {
if (control.currentIndex < (control.length - 1))
control.currentIndex++;
else
control.finished(input);
}
}
property int __index: index
property bool isBackspace: false
function selectThis() {
forceActiveFocus();
selectAll();
}
Keys.onPressed: function(event) {
if (event.key === Qt.Key_Backspace) {
clear();
const input = control.getInput();
control.currentInput = input;
isBackspace = true;
if (control.currentIndex != 0)
control.currentIndex--;
} else if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
if (control.currentIndex < (control.length - 1))
control.currentIndex++;
else
control.finished(control.getInput());
}
}
Timer {
id: __timer
interval: 100
onTriggered: {
control.currentIndex = __rootItem.__index >> 1;
__rootItem.selectAll();
}
}
}
}
Row {
id: __row
spacing: 8
Repeater {
id: __repeater
model: control.length * 2 - 1
delegate: Loader {
sourceComponent: index % 2 == 0 ? __inputDelegate : dividerDelegate
required property int index
}
}
}
}