pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import M3Shapes import Caelestia.Config import qs.components import qs.components.controls import qs.services StyledRect { id: root required property real centerScale required property int centerWidth required property var lock implicitWidth: { const w = centerWidth * 0.8; return lock.pam.buffer ? w : Math.min(w, inputField.placeholderWidth + iconWrapper.implicitWidth + enterButton.implicitWidth + input.spacing * 2 + Tokens.padding.medium * 2); } implicitHeight: input.implicitHeight + Tokens.padding.small color: Colours.tPalette.m3surfaceContainer radius: Tokens.rounding.full focus: true onActiveFocusChanged: { if (!activeFocus) forceActiveFocus(); } Keys.onPressed: event => { if (root.lock.unlocking) return; if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) inputField.placeholder.animate = false; root.lock.pam.handleKey(event); } Behavior on implicitWidth { Anim {} } StateLayer { hoverEnabled: false cursorShape: Qt.IBeamCursor onClicked: parent.forceActiveFocus() } RowLayout { id: input anchors.fill: parent anchors.margins: Tokens.padding.extraSmall spacing: Tokens.spacing.medium Item { id: iconWrapper Layout.fillHeight: true implicitWidth: height AnimLoader { anchors.centerIn: parent anchors.verticalCenterOffset: sourceComponent === iconComp ? 1 : 0 sourceComp: root.lock.pam.passwd.active ? loadingComp : iconComp } Component { id: iconComp MaterialIcon { animate: true text: { if (root.lock.pam.fprint.tries >= GlobalConfig.lock.maxFprintTries) return "fingerprint_off"; if (root.lock.pam.fprint.active) return "fingerprint"; return "lock"; } color: root.lock.pam.fprint.tries >= GlobalConfig.lock.maxFprintTries ? Colours.palette.m3error : Colours.palette.m3onSurfaceVariant fontStyle: Tokens.font.icon.builders.medium.scale(root.centerScale).build() } } Component { id: loadingComp LoadingIndicator { implicitSize: iconWrapper.height - Tokens.padding.small * 2 } } } InputField { id: inputField Layout.fillWidth: true Layout.fillHeight: true centerScale: root.centerScale pam: root.lock.pam } Item { id: enterButton implicitWidth: implicitHeight implicitHeight: { const h = enterIcon.implicitHeight + Tokens.padding.extraSmall * 2; return h % 2 === 0 ? h : h + 1; } MaterialShape { anchors.fill: parent color: root.lock.pam.buffer ? Colours.palette.m3primary : Colours.layer(Colours.palette.m3surfaceContainerHigh, 2) shape: root.lock.pam.buffer ? MaterialShape.Arrow : MaterialShape.Circle scale: !root.lock.pam.buffer ? 1 : mouse.pressed ? 0.6 : mouse.containsMouse ? 0.8 : 0.7 rotation: 90 Behavior on scale { Anim { type: Anim.FastSpatial } } Behavior on color { CAnim {} } MouseArea { id: mouse anchors.fill: parent hoverEnabled: true cursorShape: root.lock.pam.buffer ? Qt.PointingHandCursor : Qt.ArrowCursor onClicked: root.lock.pam.buffer && root.lock.pam.passwd.start() } } MaterialIcon { id: enterIcon anchors.centerIn: parent text: "arrow_forward" color: Colours.palette.m3onSurfaceVariant fontStyle: Tokens.font.icon.builders.medium.scale(root.centerScale * 1.2).build() opacity: root.lock.pam.buffer ? 0 : 1 Behavior on opacity { Anim { type: Anim.DefaultEffects } } } } } }