Skip to content

Commit

Permalink
Merge pull request #69 from eekkelund/master
Browse files Browse the repository at this point in the history
[DeviceLock] Fix #67 and add beautiful sliding gesture to codepad
  • Loading branch information
locusf authored Feb 22, 2018
2 parents 3eb6ebd + 6ebe08f commit 4622bc5
Show file tree
Hide file tree
Showing 7 changed files with 257 additions and 132 deletions.
1 change: 1 addition & 0 deletions rpm/lipstick-glacier-home-qt5.spec
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ BuildRequires: pkgconfig(Qt5Core)
BuildRequires: pkgconfig(Qt5Quick)
BuildRequires: pkgconfig(lipstick-qt5) >= 0.12.0
BuildRequires: pkgconfig(Qt5Compositor)
BuildRequires: pkgconfig(nemodevicelock)

Provides: lipstick-colorful-home-qt5

Expand Down
1 change: 1 addition & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "glacierwindowmodel.h"
#include <QScreen>


int main(int argc, char **argv)
{
HomeApplication app(argc, argv, QString());
Expand Down
112 changes: 63 additions & 49 deletions src/qml/DeviceLockUI.qml
Original file line number Diff line number Diff line change
Expand Up @@ -6,56 +6,20 @@ import QtQuick.Layouts 1.0

import org.nemomobile.lipstick 0.1
import org.nemomobile.devicelock 1.0
import org.nemomobile.dbus 1.0

import "scripts/desktop.js" as Desktop

Item {
id: root

property bool shouldAuthenticate: Lipstick.compositor.visible
&& authenticator.availableMethods !== 0
property int remainingAttempts

onShouldAuthenticateChanged: {
if (shouldAuthenticate) {
DeviceLock.authorization.requestChallenge()
} else {
authenticator.cancel()
DeviceLock.authorization.relinquishChallenge()
}
}

Component.onCompleted: {
DeviceLock.authorization.requestChallenge()
}

Connections {
target: DeviceLock.authorization
onChallengeIssued: {
authenticator.authenticate(
DeviceLock.authorization.challengeCode,
DeviceLock.authorization.allowedMethods)
}
}

Authenticator {
id: authenticator
onAuthenticated: {
DeviceLock.unlock(authenticationToken)
Desktop.instance.setLockScreen(false)
Desktop.instance.codepadVisible = false
remainingAttempts = 0
}
onFeedback: {
console.log('### still locked', feedback, attemptsRemaining)
remainingAttempts = attemptsRemaining
animation.start()
}
}
property AuthenticationInput authenticationInput

ColumnLayout {
anchors.fill: parent
spacing: Theme.itemSpacingExtraSmall
spacing: Theme.itemSpacingLarge

SequentialAnimation {
id: animation;
Expand All @@ -66,14 +30,23 @@ Item {
}
NumberAnimation { target: codePad; property: "anchors.horizontalCenterOffset"; to: 0; duration: 100 }
}
Label {
font.pixelSize: Theme.fontSizeMedium
width: parent.width
text: remainingAttempts > 0 ? qsTr("Attempts remaining:") + " " + remainingAttempts : ""
Row {
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
Label {
id: feedbackLabel
font.pixelSize: Theme.fontSizeMedium
text: " "
}
Label {
id: attemptsRemainingLabel
font.pixelSize: Theme.fontSizeMedium
text: " "
}
}
TextField {
id: lockCodeField
anchors.topMargin: Theme.itemSpacingMedium
anchors.horizontalCenter: parent.horizontalCenter
readOnly: true
echoMode: TextInput.PasswordEchoOnEdit
Expand All @@ -91,18 +64,28 @@ Item {
delegate:
Button {
id:button
opacity: 1
Layout.maximumWidth: Theme.itemWidthSmall
Layout.maximumHeight: Theme.itemHeightHuge * 2
Layout.minimumHeight: Theme.itemHeightHuge * 1.5
text: modelData
Text {
id: numLabel
text: modelData
font.pixelSize: Theme.fontSizeLarge
anchors.centerIn: parent
color: "white"
}
onClicked: {
if (button.text !== "Ca" && button.text !== "OK") {
lockCodeField.insert(lockCodeField.cursorPosition, button.text)
displayOffTimer.restart()
feedbackLabel.text = " "
attemptsRemainingLabel.text = " "
if (numLabel.text !== "Ca" && numLabel.text !== "OK") {
lockCodeField.insert(lockCodeField.cursorPosition, numLabel.text)
} else {
if (button.text === "OK") {
authenticator.enterLockCode(lockCodeField.text)
if (numLabel.text === "OK") {
authenticationInput.enterSecurityCode(lockCodeField.text)
lockCodeField.text = ""
} else if (button.text === "Ca"){
} else if (numLabel.text === "Ca"){
lockCodeField.text = ""
}
}
Expand All @@ -111,4 +94,35 @@ Item {
}
}
}
function displayFeedback(feedback, data) {

switch(feedback) {

case AuthenticationInput.EnterSecurityCode:
feedbackLabel.text = qsTr("Enter security code")
break

case AuthenticationInput.IncorrectSecurityCode:
feedbackLabel.text = qsTr("Incorrect code")
if(authenticationInput.maximumAttempts !== -1) {
attemptsRemainingLabel.text = qsTr("("+(authenticationInput.maximumAttempts-data.attemptsRemaining)+
"/"+authenticationInput.maximumAttempts+")")
}
animation.start()
break
case AuthenticationInput.TemporarilyLocked:
feedbackLabel.text = qsTr("Temporarily locked")
}
}
function displayError(error) {
console.log("displayError "+error)
}

Connections {
target: root.authenticationInput

onFeedback: root.displayFeedback(feedback, data)
onError: root.displayError(error)
}

}
182 changes: 182 additions & 0 deletions src/qml/Lockscreen.qml
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,139 @@ Image {
}
}

// Swipes on the lockscreen
MouseArea {
id:mouseArea

property bool gestureStarted: false
property string gesture: ""
property int startX
property int threshold: Theme.itemHeightHuge * 2
property int swipeDistance
property string action: ""

anchors.fill: parent

onPressed: {
startX = mouseX;
}
onMouseXChanged: {
// Checks which was it left or right swipe
if(mouseX > (startX+threshold)) {
gesture = "right"
gestureStarted = true;
}
else if(mouseX < (startX+threshold)) {
gesture = "left"
gestureStarted = true;
}
// Makes codepad follow the swipe
if(codePad.inView) {
if(gesture == "right") {
swipeDistance = mouseX - startX
codePad.x = swipeDistance
}
if(gesture == "left") {
swipeDistance = startX - mouseX
codePad.x = -swipeDistance
}
}else {
if(gesture == "right") {
swipeDistance = mouseX - startX
codePad.x = swipeDistance - parent.width
}
else if(gesture == "left") {
swipeDistance = startX - mouseX
codePad.x = parent.width - swipeDistance
}

}

}
// Animation to snap codepad into view or out of view
onReleased: {
displayOffTimer.restart()
if(codePad.inView) {
if(gesture == "right") {
if(swipeDistance > threshold) {
startCodePadAnimation(parent.width)
codePad.inView = false
}else {
startCodePadAnimation(0)
codePad.inView = true
}
}else if(gesture == "left") {
if(swipeDistance > threshold) {
startCodePadAnimation(-parent.width)
codePad.inView = false
}else {
startCodePadAnimation(0)
codePad.inView = true
}
}
}else {
if(swipeDistance > threshold) {
startCodePadAnimation(0)
codePad.inView = true
}else {
if(gesture == "right") {
startCodePadAnimation(-parent.width)
codePad.inView = false
}
else {
startCodePadAnimation(parent.width)
codePad.inView = false
}
}
}

gestureStarted = false
}
function startCodePadAnimation(value) {
snapCodePadAnimation.valueTo = value
snapCodePadAnimation.start()
}

}
SequentialAnimation {
id: snapCodePadAnimation

property alias valueTo: codePadAnimation.to

NumberAnimation {
id: codePadAnimation
target: codePad
property: "x"
duration: 200
easing.type: Easing.OutQuint
}
}
SequentialAnimation {
id: unlockAnimation
property alias valueTo: unlockNumAnimation.to
property alias setProperty: unlockNumAnimation.property


NumberAnimation {
id: unlockNumAnimation
target: lockScreen
property: "y"
to: -height
duration: 250
easing.type: Easing.OutQuint
}
onStopped: {
setLockScreen(false)
}
}

Connections {
target:Lipstick.compositor
onDisplayOff: {
displayOn = false
displayOffTimer.stop()
codePad.x = -parent.width
codePad.inView = false
}
onDisplayOn:{
displayOn = true
Expand Down Expand Up @@ -66,7 +190,65 @@ Image {
}
}
}
DeviceLockUI {
id: codePad
property bool inView: false
property bool gestureStarted: mouseArea.gestureStarted

x: width * 2
visible: DeviceLock.state == DeviceLock.Locked && lockscreenVisible()
width: lockScreen.width
height: lockScreen.height / 2
opacity: (1-Math.abs((1 - (-1)) * (x - (-parent.width)) / (parent.width - (-parent.width)) + (-1)))

authenticationInput: DeviceLockAuthenticationInput {

readonly property bool unlocking: registered
&& DeviceLock.state >= DeviceLock.Locked && DeviceLock.state < DeviceLock.Undefined

registered: lockscreenVisible()
active: lockscreenVisible()

onUnlockingChanged: {
if (unlocking) {
DeviceLock.unlock()
} else {
DeviceLock.cancel()
}
}
onAuthenticationEnded: {
if(confirmed) {
unlockAnimationHelper(mouseArea.gesture)
}else {

}

}
function unlockAnimationHelper(gesture) {
if(gesture == "left") {
unlockAnimation.setProperty = "x"
unlockAnimation.valueTo = -width
unlockAnimation.start()
}
if(gesture == "right") {
unlockAnimation.setProperty = "x"
unlockAnimation.valueTo = width
unlockAnimation.start()
}
}
}

anchors {
verticalCenter: lockScreen.verticalCenter
}
onGestureStartedChanged: {
if(gestureStarted) {
mouseArea.z = 2
}else {
mouseArea.z = 0
}
}
}
ListView {
id: notificationColumn
opacity: codePad.visible ? 1 - codePad.opacity : 1
Expand Down
Loading

0 comments on commit 4622bc5

Please sign in to comment.