mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 22:33:08 +00:00
This converts many of the animation durations to Kirigami units so that they can be controlled system wide. It also speeds up several of the animation durations (ex. in folio) from 800ms to 400ms to improve the feel and responsiveness of the shell.
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: Kirigami.Units.shortDuration }
|
|
}
|
|
}
|
|
|
|
// 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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|