mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
232 lines
7.4 KiB
QML
232 lines
7.4 KiB
QML
// SPDX-FileCopyrightText: 2020-2024 Devin Lin <devin@kde.org>
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
import QtQuick.Effects
|
|
|
|
import org.kde.plasma.components 3.0 as PlasmaComponents
|
|
import org.kde.plasma.core as PlasmaCore
|
|
import org.kde.plasma.workspace.keyboardlayout 1.0
|
|
import org.kde.plasma.private.mobileshell as MobileShell
|
|
|
|
import org.kde.kirigami 2.12 as Kirigami
|
|
|
|
Item {
|
|
id: root
|
|
required property real openProgress
|
|
required property var lockScreenState
|
|
|
|
property alias passwordBar: passwordBar
|
|
|
|
MobileShell.HapticsEffect {
|
|
id: haptics
|
|
}
|
|
|
|
// Column layout - most cases
|
|
ColumnLayout {
|
|
id: keypadVerticalContainer
|
|
visible: root.height > Kirigami.Units.gridUnit * 25
|
|
|
|
anchors.centerIn: parent
|
|
spacing: Kirigami.Units.gridUnit * 2
|
|
|
|
LayoutItemProxy {
|
|
id: verticalHeaderProxy
|
|
target: header
|
|
}
|
|
LayoutItemProxy { target: keypadGrid }
|
|
|
|
states: [
|
|
State {
|
|
name: "keypad"
|
|
when: !lockScreenState.isKeyboardMode
|
|
AnchorChanges {
|
|
target: verticalHeaderProxy; anchors.top: keypadVerticalContainer.top
|
|
}
|
|
PropertyChanges {
|
|
target: verticalHeaderProxy; anchors.verticalCenterOffset: 0
|
|
}
|
|
},
|
|
State {
|
|
name: "keyboard"
|
|
when: lockScreenState.isKeyboardMode
|
|
AnchorChanges {
|
|
target: verticalHeaderProxy; anchors.verticalCenter: keypadVerticalContainer.verticalCenter
|
|
}
|
|
PropertyChanges {
|
|
target: verticalHeaderProxy; anchors.verticalCenterOffset: -Kirigami.Units.gridUnit * 3
|
|
}
|
|
}
|
|
]
|
|
|
|
transitions: Transition {
|
|
AnchorAnimation {
|
|
easing.type: Easing.OutCirc
|
|
duration: openProgress > 0.5 ? 300 : 0
|
|
}
|
|
}
|
|
}
|
|
|
|
// Row layout - used when there is restricted height
|
|
RowLayout {
|
|
id: keypadHorizontalContainer
|
|
visible: !keypadVerticalContainer.visible
|
|
|
|
anchors.centerIn: parent
|
|
spacing: Kirigami.Units.gridUnit * 2
|
|
|
|
LayoutItemProxy {
|
|
id: horizontalHeaderProxy
|
|
target: header
|
|
}
|
|
LayoutItemProxy { target: keypadGrid }
|
|
|
|
states: [
|
|
State {
|
|
name: "keypad"
|
|
when: !lockScreenState.isKeyboardMode
|
|
AnchorChanges {
|
|
target: horizontalHeaderProxy; anchors.left: keypadHorizontalContainer.left
|
|
}
|
|
},
|
|
State {
|
|
name: "keyboard"
|
|
when: lockScreenState.isKeyboardMode
|
|
AnchorChanges {
|
|
target: horizontalHeaderProxy; anchors.horizontalCenter: keypadHorizontalContainer.horizontalCenter
|
|
}
|
|
}
|
|
]
|
|
|
|
transitions: Transition {
|
|
AnchorAnimation {
|
|
easing.type: Easing.OutCirc
|
|
duration: openProgress > 0.5 ? 300 : 0
|
|
}
|
|
}
|
|
}
|
|
|
|
ColumnLayout {
|
|
id: header
|
|
spacing: Kirigami.Units.gridUnit
|
|
|
|
// label ("wrong pin", "enter pin")
|
|
Label {
|
|
id: descriptionLabel
|
|
Layout.alignment: Qt.AlignHCenter
|
|
opacity: root.lockScreenState.password.length === 0 ? 1 : 0
|
|
text: root.lockScreenState.pinLabel
|
|
font.pointSize: 12
|
|
font.bold: true
|
|
color: 'white'
|
|
|
|
// Enforce extra margin at top of vertical container
|
|
Layout.topMargin: keypadVerticalContainer.visible ? Kirigami.Units.gridUnit * 3 : 0
|
|
|
|
Behavior on opacity {
|
|
NumberAnimation { duration: 200 }
|
|
}
|
|
}
|
|
|
|
// pin display and bar
|
|
PasswordBar {
|
|
id: passwordBar
|
|
Layout.preferredWidth: Kirigami.Units.gridUnit * 14
|
|
Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5
|
|
|
|
lockScreenState: root.lockScreenState
|
|
isKeypadOpen: root.openProgress >= 0.9
|
|
enabled: root.openProgress >= 0.8
|
|
}
|
|
}
|
|
|
|
GridLayout {
|
|
id: keypadGrid
|
|
columnSpacing: Kirigami.Units.gridUnit
|
|
rowSpacing: Kirigami.Units.gridUnit
|
|
uniformCellHeights: true
|
|
uniformCellWidths: true
|
|
|
|
readonly property real intendedWidth: Kirigami.Units.gridUnit * 14
|
|
|
|
Layout.preferredWidth: Kirigami.Units.gridUnit * 14
|
|
Layout.preferredHeight: Kirigami.Units.gridUnit * 22
|
|
|
|
readonly property real cellLength: (intendedWidth - columnSpacing * 2) / 3
|
|
|
|
columns: 3
|
|
|
|
// numpad keys
|
|
Repeater {
|
|
model: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "R", "0", "E"]
|
|
|
|
delegate: AbstractButton {
|
|
id: button
|
|
implicitWidth: keypadGrid.cellLength
|
|
implicitHeight: keypadGrid.cellLength
|
|
visible: modelData.length > 0
|
|
enabled: root.openProgress >= 0.8 && !lockScreenState.isKeyboardMode // Only enable after a certain point in animation
|
|
|
|
opacity: enabled
|
|
Behavior on opacity {
|
|
SequentialAnimation {
|
|
PauseAnimation { duration: 20 * index }
|
|
NumberAnimation { duration: 300 }
|
|
}
|
|
}
|
|
|
|
background: Rectangle {
|
|
readonly property real restingOpacity: (modelData !== "R" && modelData !== "E") ? 0.2 : 0.0
|
|
radius: width
|
|
color: Qt.rgba(255, 255, 255,
|
|
button.pressed ? 0.5 : restingOpacity)
|
|
}
|
|
|
|
onPressedChanged: {
|
|
if (pressed) {
|
|
haptics.buttonVibrate();
|
|
}
|
|
}
|
|
|
|
onClicked: {
|
|
if (modelData === "R") {
|
|
passwordBar.backspace();
|
|
} else if (modelData === "E") {
|
|
passwordBar.enter();
|
|
} else {
|
|
passwordBar.keyPress(modelData);
|
|
}
|
|
}
|
|
|
|
onPressAndHold: {
|
|
if (modelData === "R") {
|
|
haptics.buttonVibrate();
|
|
passwordBar.clear();
|
|
}
|
|
}
|
|
|
|
contentItem: Item {
|
|
PlasmaComponents.Label {
|
|
visible: modelData !== "R" && modelData !== "E"
|
|
text: modelData
|
|
anchors.centerIn: parent
|
|
font.pointSize: 18
|
|
color: 'white'
|
|
}
|
|
|
|
Kirigami.Icon {
|
|
visible: modelData === "R" || modelData === "E"
|
|
anchors.centerIn: parent
|
|
width: Kirigami.Units.iconSizes.small
|
|
height: Kirigami.Units.iconSizes.small
|
|
source: modelData === "R" ? "edit-clear" : "go-next"
|
|
Kirigami.Theme.inherit: false
|
|
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|