mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-08-03 10:14:45 +00:00
Fix text syncing
This commit is contained in:
parent
07142481bf
commit
38f9e4871d
4 changed files with 129 additions and 82 deletions
|
|
@ -23,12 +23,6 @@ Rectangle {
|
||||||
color: Kirigami.ColorUtils.adjustColor(PlasmaCore.Theme.backgroundColor, {"alpha": 0.9*255})
|
color: Kirigami.ColorUtils.adjustColor(PlasmaCore.Theme.backgroundColor, {"alpha": 0.9*255})
|
||||||
property string pinLabel: qsTr("Enter PIN")
|
property string pinLabel: qsTr("Enter PIN")
|
||||||
|
|
||||||
// for displaying temporary number in pin dot display
|
|
||||||
property int previewCharIndex: -2
|
|
||||||
|
|
||||||
// if waiting for result of auth
|
|
||||||
property bool waitingForAuth: false
|
|
||||||
|
|
||||||
// colour calculations
|
// colour calculations
|
||||||
property color buttonColor: Qt.lighter(PlasmaCore.Theme.backgroundColor, 1.3)
|
property color buttonColor: Qt.lighter(PlasmaCore.Theme.backgroundColor, 1.3)
|
||||||
property color buttonPressedColor: Qt.darker(PlasmaCore.Theme.backgroundColor, 1.08)
|
property color buttonPressedColor: Qt.darker(PlasmaCore.Theme.backgroundColor, 1.08)
|
||||||
|
|
@ -48,70 +42,24 @@ Rectangle {
|
||||||
|
|
||||||
signal passwordChanged()
|
signal passwordChanged()
|
||||||
|
|
||||||
// keypad functions
|
|
||||||
function reset() {
|
function reset() {
|
||||||
waitingForAuth = false;
|
passwordBar.reset();
|
||||||
root.password = "";
|
|
||||||
passwordChanged();
|
|
||||||
keypadRoot.pinLabel = qsTr("Enter PIN");
|
|
||||||
}
|
|
||||||
|
|
||||||
function backspace() {
|
|
||||||
if (!keypadRoot.waitingForAuth) {
|
|
||||||
keypadRoot.previewCharIndex = -2;
|
|
||||||
root.password = root.password.substr(0, root.password.length - 1);
|
|
||||||
passwordChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function clear() {
|
|
||||||
if (!keypadRoot.waitingForAuth) {
|
|
||||||
keypadRoot.previewCharIndex = -2;
|
|
||||||
root.password = "";
|
|
||||||
passwordChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function enter() {
|
|
||||||
if (root.password !== "") { // prevent typing lock when password is empty
|
|
||||||
keypadRoot.waitingForAuth = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't try to unlock if there is a timeout (unlock once unlocked)
|
|
||||||
if (!authenticator.graceLocked) {
|
|
||||||
authenticator.tryUnlock(root.password);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function keyPress(data) {
|
|
||||||
if (!keypadRoot.waitingForAuth) {
|
|
||||||
if (keypadRoot.pinLabel !== qsTr("Enter PIN")) {
|
|
||||||
keypadRoot.pinLabel = qsTr("Enter PIN");
|
|
||||||
}
|
|
||||||
keypadRoot.previewCharIndex = root.password.length;
|
|
||||||
root.password += data
|
|
||||||
passwordChanged();
|
|
||||||
|
|
||||||
// trigger turning letter into dot later
|
|
||||||
letterTimer.restart();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: authenticator
|
target: authenticator
|
||||||
function onSucceeded() {
|
function onSucceeded() {
|
||||||
pinLabel = qsTr("Logging in...");
|
passwordBar.pinLabel = qsTr("Logging in...");
|
||||||
keypadRoot.waitingForAuth = false;
|
passwordBar.waitingForAuth = false;
|
||||||
}
|
}
|
||||||
function onFailed() {
|
function onFailed() {
|
||||||
root.password = "";
|
root.password = "";
|
||||||
passwordChanged();
|
passwordBar.pinLabel = qsTr("Wrong PIN");
|
||||||
pinLabel = qsTr("Wrong PIN");
|
passwordBar.waitingForAuth = false;
|
||||||
keypadRoot.waitingForAuth = false;
|
|
||||||
}
|
}
|
||||||
function onGraceLockedChanged() {
|
function onGraceLockedChanged() {
|
||||||
// try authenticating if it was waiting for grace lock to stop and it has stopped
|
// try authenticating if it was waiting for grace lock to stop and it has stopped
|
||||||
if (!authenticator.graceLocked && keypadRoot.waitingForAuth) {
|
if (!authenticator.graceLocked && passwordBar.waitingForAuth) {
|
||||||
authenticator.tryUnlock(root.password);
|
authenticator.tryUnlock(root.password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -121,26 +69,15 @@ Rectangle {
|
||||||
Keys.onPressed: {
|
Keys.onPressed: {
|
||||||
if (event.modifiers === Qt.NoModifier) {
|
if (event.modifiers === Qt.NoModifier) {
|
||||||
if (event.key === Qt.Key_Backspace) {
|
if (event.key === Qt.Key_Backspace) {
|
||||||
keypadRoot.backspace();
|
passwordBar.backspace();
|
||||||
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
||||||
keypadRoot.enter();
|
passwordBar.enter();
|
||||||
} else if (event.text != "") {
|
} else if (event.text != "") {
|
||||||
keypadRoot.keyPress(event.text);
|
passwordBar.keyPress(event.text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// trigger turning letter into dot after 500 milliseconds
|
|
||||||
Timer {
|
|
||||||
id: letterTimer
|
|
||||||
interval: 500
|
|
||||||
running: false
|
|
||||||
repeat: false
|
|
||||||
onTriggered: {
|
|
||||||
keypadRoot.previewCharIndex = -2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RectangularGlow {
|
RectangularGlow {
|
||||||
anchors.topMargin: 1
|
anchors.topMargin: 1
|
||||||
anchors.fill: passwordBar
|
anchors.fill: passwordBar
|
||||||
|
|
@ -162,8 +99,15 @@ Rectangle {
|
||||||
|
|
||||||
keypadOpen: swipeProgress === 1
|
keypadOpen: swipeProgress === 1
|
||||||
password: root.password
|
password: root.password
|
||||||
previewCharIndex: keypadRoot.previewCharIndex
|
previewCharIndex: -2
|
||||||
pinLabel: keypadRoot.pinLabel
|
pinLabel: qsTr("Enter PIN")
|
||||||
|
|
||||||
|
onChangePassword: root.password = password
|
||||||
|
Binding {
|
||||||
|
target: passwordBar
|
||||||
|
property: "password"
|
||||||
|
value: root.password
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// actual number keys
|
// actual number keys
|
||||||
|
|
@ -238,16 +182,16 @@ Rectangle {
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (modelData === "R") {
|
if (modelData === "R") {
|
||||||
keypadRoot.backspace();
|
passwordBar.backspace();
|
||||||
} else if (modelData === "E") {
|
} else if (modelData === "E") {
|
||||||
keypadRoot.enter();
|
passwordBar.enter();
|
||||||
} else {
|
} else {
|
||||||
keypadRoot.keyPress(modelData);
|
passwordBar.keyPress(modelData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onPressAndHold: {
|
onPressAndHold: {
|
||||||
if (modelData === "R") {
|
if (modelData === "R") {
|
||||||
clear();
|
passwordBar.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,7 @@ PlasmaCore.ColorScope {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
property int columnHeight: units.gridUnit * 20
|
property int columnHeight: units.gridUnit * 20
|
||||||
|
property int oldContentY: contentY
|
||||||
|
|
||||||
height: columnHeight + root.height
|
height: columnHeight + root.height
|
||||||
contentHeight: columnHeight + root.height
|
contentHeight: columnHeight + root.height
|
||||||
|
|
@ -253,9 +254,10 @@ PlasmaCore.ColorScope {
|
||||||
|
|
||||||
// wipe password if it is more than half way down the screen
|
// wipe password if it is more than half way down the screen
|
||||||
onContentYChanged: {
|
onContentYChanged: {
|
||||||
if (contentY < columnHeight / 2) {
|
if (contentY < columnHeight / 2 && oldContentY >= columnHeight / 2) {
|
||||||
keypad.reset();
|
keypad.reset();
|
||||||
}
|
}
|
||||||
|
oldContentY = contentY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ Item {
|
||||||
}
|
}
|
||||||
height: 1
|
height: 1
|
||||||
color: Qt.rgba(1, 1, 1, 0.5)
|
color: Qt.rgba(1, 1, 1, 0.5)
|
||||||
|
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
@ -77,6 +78,7 @@ Item {
|
||||||
}
|
}
|
||||||
height: 1
|
height: 1
|
||||||
color: Qt.rgba(1, 1, 1, 0.5)
|
color: Qt.rgba(1, 1, 1, 0.5)
|
||||||
|
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,81 @@ Rectangle {
|
||||||
property bool isPinMode: true
|
property bool isPinMode: true
|
||||||
|
|
||||||
property string password
|
property string password
|
||||||
|
|
||||||
|
// for displaying temporary number in pin dot display
|
||||||
property int previewCharIndex
|
property int previewCharIndex
|
||||||
|
|
||||||
property string pinLabel
|
property string pinLabel
|
||||||
property bool keypadOpen
|
property bool keypadOpen
|
||||||
|
|
||||||
|
// if waiting for result of auth
|
||||||
|
property bool waitingForAuth: false
|
||||||
|
|
||||||
property color headerTextColor: Kirigami.ColorUtils.adjustColor(PlasmaCore.Theme.textColor, {"alpha": 0.75*255})
|
property color headerTextColor: Kirigami.ColorUtils.adjustColor(PlasmaCore.Theme.textColor, {"alpha": 0.75*255})
|
||||||
property color headerTextInactiveColor: Kirigami.ColorUtils.adjustColor(PlasmaCore.Theme.textColor, {"alpha": 0.4*255})
|
property color headerTextInactiveColor: Kirigami.ColorUtils.adjustColor(PlasmaCore.Theme.textColor, {"alpha": 0.4*255})
|
||||||
|
|
||||||
|
signal changePassword();
|
||||||
|
|
||||||
|
// keypad functions
|
||||||
|
function reset() {
|
||||||
|
waitingForAuth = false;
|
||||||
|
root.password = "";
|
||||||
|
changePassword();
|
||||||
|
root.pinLabel = qsTr("Enter PIN");
|
||||||
|
}
|
||||||
|
|
||||||
|
function backspace() {
|
||||||
|
if (!root.waitingForAuth) {
|
||||||
|
root.previewCharIndex = -2;
|
||||||
|
root.password = root.password.substr(0, root.password.length - 1);
|
||||||
|
changePassword();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
if (!root.waitingForAuth) {
|
||||||
|
root.previewCharIndex = -2;
|
||||||
|
root.password = "";
|
||||||
|
changePassword();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function enter() {
|
||||||
|
if (root.password !== "") { // prevent typing lock when password is empty
|
||||||
|
root.waitingForAuth = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't try to unlock if there is a timeout (unlock once unlocked)
|
||||||
|
if (!authenticator.graceLocked) {
|
||||||
|
authenticator.tryUnlock(root.password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyPress(data) {
|
||||||
|
if (!root.waitingForAuth) {
|
||||||
|
if (root.pinLabel !== qsTr("Enter PIN")) {
|
||||||
|
root.pinLabel = qsTr("Enter PIN");
|
||||||
|
}
|
||||||
|
root.previewCharIndex = root.password.length;
|
||||||
|
root.password += data
|
||||||
|
changePassword();
|
||||||
|
|
||||||
|
// trigger turning letter into dot later
|
||||||
|
letterTimer.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trigger turning letter into dot after 500 milliseconds
|
||||||
|
Timer {
|
||||||
|
id: letterTimer
|
||||||
|
interval: 500
|
||||||
|
running: false
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
root.previewCharIndex = -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// we need to use a listmodel to avoid all delegates from reloading
|
// we need to use a listmodel to avoid all delegates from reloading
|
||||||
ListModel {
|
ListModel {
|
||||||
id: dotDisplayModel
|
id: dotDisplayModel
|
||||||
|
|
@ -43,10 +111,41 @@ Rectangle {
|
||||||
|
|
||||||
// hidden textfield so that the virtual keyboard shows up
|
// hidden textfield so that the virtual keyboard shows up
|
||||||
TextField {
|
TextField {
|
||||||
visible: false
|
|
||||||
id: textField
|
id: textField
|
||||||
|
visible: false
|
||||||
focus: keypadOpen && !isPinMode
|
focus: keypadOpen && !isPinMode
|
||||||
z: 1
|
z: 1
|
||||||
|
|
||||||
|
property bool externalEdit: false
|
||||||
|
property string prevText: ""
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
function onChangePassword() {
|
||||||
|
if (textField.text != root.password) {
|
||||||
|
textField.externalEdit = true;
|
||||||
|
textField.text = root.password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onEditingFinished: {
|
||||||
|
if (textField.focus) {
|
||||||
|
root.enter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onTextChanged: {
|
||||||
|
if (!externalEdit) {
|
||||||
|
if (prevText.length > text.length) { // backspace
|
||||||
|
for (let i = 0; i < (prevText.length - text.length); i++) {
|
||||||
|
root.backspace();
|
||||||
|
}
|
||||||
|
} else if (text.length > 0) { // key enter
|
||||||
|
root.keyPress(text.charAt(text.length - 1));
|
||||||
|
}
|
||||||
|
prevText = text;
|
||||||
|
}
|
||||||
|
externalEdit = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// toggle between showing keypad and not
|
// toggle between showing keypad and not
|
||||||
|
|
@ -123,7 +222,7 @@ Rectangle {
|
||||||
scale: 0
|
scale: 0
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: width
|
radius: width
|
||||||
color: keypadRoot.waitingForAuth ? root.headerTextInactiveColor : root.headerTextColor // dim when waiting for auth
|
color: root.waitingForAuth ? root.headerTextInactiveColor : root.headerTextColor // dim when waiting for auth
|
||||||
|
|
||||||
PropertyAnimation {
|
PropertyAnimation {
|
||||||
id: dotAnimation
|
id: dotAnimation
|
||||||
|
|
@ -137,7 +236,7 @@ Rectangle {
|
||||||
id: charLabel
|
id: charLabel
|
||||||
scale: 0
|
scale: 0
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
color: keypadRoot.waitingForAuth ? root.headerTextInactiveColor : root.headerTextColor // dim when waiting for auth
|
color: root.waitingForAuth ? root.headerTextInactiveColor : root.headerTextColor // dim when waiting for auth
|
||||||
text: model.char
|
text: model.char
|
||||||
font.pointSize: 12
|
font.pointSize: 12
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue