nosignal-shell/modules/lock/LockSurface.qml
2026-04-23 03:45:22 +10:00

229 lines
6.1 KiB
QML

pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Effects
import Quickshell.Wayland
import Caelestia.Config
import qs.components
import qs.services
WlSessionLockSurface {
id: root
required property WlSessionLock lock
required property Pam pam
readonly property alias unlocking: unlockAnim.running
contentItem.Config.screen: screen.name
contentItem.Tokens.screen: screen.name
color: "transparent"
Connections {
function onUnlock(): void {
unlockAnim.start();
}
target: root.lock
}
SequentialAnimation {
id: unlockAnim
ParallelAnimation {
Anim {
target: lockContent
properties: "implicitWidth,implicitHeight"
to: lockContent.size
type: Anim.DefaultSpatial
}
Anim {
target: lockBg
property: "radius"
to: lockContent.radius
}
Anim {
target: content
property: "scale"
to: 0
type: Anim.DefaultSpatial
}
Anim {
target: content
property: "opacity"
to: 0
type: Anim.StandardSmall
}
Anim {
target: lockIcon
property: "opacity"
to: 1
type: Anim.StandardLarge
}
Anim {
target: background
property: "opacity"
to: 0
type: Anim.StandardLarge
}
SequentialAnimation {
PauseAnimation {
duration: Tokens.anim.durations.small
}
Anim {
type: Anim.Standard
target: lockContent
property: "opacity"
to: 0
}
}
}
PropertyAction {
target: root.lock
property: "locked"
value: false
}
}
ParallelAnimation {
id: initAnim
running: true
Anim {
target: background
property: "opacity"
to: 1
type: Anim.StandardLarge
}
SequentialAnimation {
ParallelAnimation {
Anim {
target: lockContent
property: "scale"
to: 1
type: Anim.FastSpatial
}
Anim {
target: lockContent
property: "rotation"
to: 360
duration: Tokens.anim.durations.expressiveFastSpatial
easing: Tokens.anim.standardAccel
}
}
ParallelAnimation {
Anim {
target: lockIcon
property: "rotation"
to: 360
easing: Tokens.anim.standardDecel
}
Anim {
type: Anim.DefaultEffects
target: lockIcon
property: "opacity"
to: 0
}
Anim {
type: Anim.DefaultEffects
target: content
property: "opacity"
to: 1
}
Anim {
target: content
property: "scale"
to: 1
type: Anim.DefaultSpatial
}
Anim {
target: lockBg
property: "radius"
to: lockContent.Tokens.rounding.extraLarge * 1.5
}
Anim {
target: lockContent
property: "implicitWidth"
to: (root.screen?.height ?? 0) * lockContent.Tokens.sizes.lock.heightMult * lockContent.Tokens.sizes.lock.ratio
type: Anim.DefaultSpatial
}
Anim {
target: lockContent
property: "implicitHeight"
to: (root.screen?.height ?? 0) * lockContent.Tokens.sizes.lock.heightMult
type: Anim.DefaultSpatial
}
}
}
}
ScreencopyView {
id: background
anchors.fill: parent
captureSource: root.screen
opacity: 0
layer.enabled: true
layer.effect: MultiEffect {
autoPaddingEnabled: false
blurEnabled: true
blur: 1
blurMax: 64
blurMultiplier: 1
}
}
Item {
id: lockContent
readonly property int size: lockIcon.implicitHeight + Tokens.padding.large * 4
readonly property int radius: size / 4 * Tokens.rounding.scale
anchors.centerIn: parent
implicitWidth: size
implicitHeight: size
rotation: 180
scale: 0
StyledRect {
id: lockBg
anchors.fill: parent
color: Colours.palette.m3surface
radius: parent.radius
opacity: Colours.transparency.enabled ? Colours.transparency.base : 1
layer.enabled: true
layer.effect: MultiEffect {
shadowEnabled: true
blurMax: 15
shadowColor: Qt.alpha(Colours.palette.m3shadow, 0.7)
}
}
MaterialIcon {
id: lockIcon
anchors.centerIn: parent
text: "lock"
fontStyle: Tokens.font.icon.builders.extraLarge.scale(4).weight(Font.Bold).build()
rotation: 180
}
Content {
id: content
anchors.centerIn: parent
width: (root.screen?.height ?? 0) * Tokens.sizes.lock.heightMult * Tokens.sizes.lock.ratio - Tokens.padding.extraLargeIncreased
height: (root.screen?.height ?? 0) * Tokens.sizes.lock.heightMult - Tokens.padding.extraLargeIncreased
lock: root
opacity: 0
scale: 0
}
}
}