mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-29 15:03:09 +00:00
Implement lockscreen mockups
This commit is contained in:
parent
da3d3c022f
commit
46022538ac
13 changed files with 1326 additions and 132 deletions
|
|
@ -1,26 +1,65 @@
|
|||
/*
|
||||
Copyright (C) 2019 Nicolas Fella <nicolas.fella@gmx.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.8
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Controls 2.5
|
||||
import QtGraphicalEffects 1.12
|
||||
import org.kde.plasma.core 2.0
|
||||
|
||||
ColumnLayout {
|
||||
readonly property bool softwareRendering: GraphicsInfo.api === GraphicsInfo.Software
|
||||
|
||||
|
||||
property int alignment
|
||||
Layout.alignment: alignment
|
||||
spacing: units.gridUnit
|
||||
|
||||
Label {
|
||||
text: Qt.formatTime(timeSource.data["Local"]["DateTime"])
|
||||
text: Qt.formatTime(timeSource.data["Local"]["DateTime"], "h:mm ap")
|
||||
color: ColorScope.textColor
|
||||
style: softwareRendering ? Text.Outline : Text.Normal
|
||||
styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" //no outline, doesn't matter
|
||||
font.pointSize: 40
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" // no outline, doesn't matter
|
||||
|
||||
Layout.alignment: alignment
|
||||
font.weight: Font.Light // this font weight may switch to regular on distros that don't have a light variant
|
||||
font.pointSize: 36
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
verticalOffset: 1
|
||||
radius: 4
|
||||
samples: 6
|
||||
color: "#757575"
|
||||
}
|
||||
}
|
||||
Label {
|
||||
text: Qt.formatDate(timeSource.data["Local"]["DateTime"], Qt.DefaultLocaleLongDate)
|
||||
text: Qt.formatDate(timeSource.data["Local"]["DateTime"], "ddd, MMM d")
|
||||
color: ColorScope.textColor
|
||||
style: softwareRendering ? Text.Outline : Text.Normal
|
||||
styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" //no outline, doesn't matter
|
||||
font.pointSize: 16
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" // no outline, doesn't matter
|
||||
|
||||
Layout.alignment: alignment
|
||||
font.pointSize: 10
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
verticalOffset: 1
|
||||
radius: 4
|
||||
samples: 6
|
||||
color: "#757575"
|
||||
}
|
||||
}
|
||||
DataSource {
|
||||
id: timeSource
|
||||
|
|
|
|||
56
look-and-feel/contents/lockscreen/DraggableDelegate.qml
Normal file
56
look-and-feel/contents/lockscreen/DraggableDelegate.qml
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 2019 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import QtQuick 2.10
|
||||
import org.kde.kirigami 2.11 as Kirigami
|
||||
|
||||
MouseArea {
|
||||
id: delegate
|
||||
|
||||
property Item contentItem
|
||||
property bool draggable: false
|
||||
signal dismissRequested
|
||||
|
||||
anchors.fill: contentItem
|
||||
implicitWidth: contentItem ? contentItem.implicitWidth : 0
|
||||
implicitHeight: contentItem ? contentItem.implicitHeight : 0
|
||||
opacity: 1 - Math.min(1, 1.5 * Math.abs(x) / width)
|
||||
|
||||
drag {
|
||||
axis: Drag.XAxis
|
||||
target: draggable && Kirigami.Settings.tabletMode ? this : null
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
if (Math.abs(x) > width / 2) {
|
||||
delegate.dismissRequested();
|
||||
} else {
|
||||
slideAnim.restart();
|
||||
}
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
id: slideAnim
|
||||
target: delegate
|
||||
property: "x"
|
||||
to: 0
|
||||
duration: units.longDuration
|
||||
}
|
||||
}
|
||||
227
look-and-feel/contents/lockscreen/Keypad.qml
Normal file
227
look-and-feel/contents/lockscreen/Keypad.qml
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
Copyright (C) 2020 Devin Lin <espidev@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtGraphicalEffects 1.12
|
||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.workspace.keyboardlayout 1.0
|
||||
|
||||
Rectangle {
|
||||
color: Qt.rgba(250, 250, 250, 0.85) // slightly translucent background, for key contrast
|
||||
property string pinLabel: qsTr("Enter PIN")
|
||||
|
||||
// for displaying temporary number in pin dot display
|
||||
property string lastKeyPressValue: "0"
|
||||
property int indexWithNumber: -2
|
||||
|
||||
// keypad functions
|
||||
function backspace() {
|
||||
lastKeyPressValue = "0";
|
||||
indexWithNumber = -2;
|
||||
root.password = root.password.substr(0, root.password.length - 1);
|
||||
}
|
||||
|
||||
function enter() {
|
||||
authenticator.tryUnlock(root.password);
|
||||
}
|
||||
|
||||
function keyPress(data) {
|
||||
if (keypad.pinLabel !== qsTr("Enter PIN")) {
|
||||
keypad.pinLabel = qsTr("Enter PIN");
|
||||
}
|
||||
lastKeyPressValue = data;
|
||||
indexWithNumber = root.password.length;
|
||||
root.password += data
|
||||
|
||||
// trigger turning letter into dot later
|
||||
letterTimer.restart();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: authenticator
|
||||
function onFailed() {
|
||||
root.password = "";
|
||||
pinLabel = qsTr("Wrong PIN")
|
||||
}
|
||||
}
|
||||
|
||||
// listen for keyboard events
|
||||
Keys.onPressed: {
|
||||
if (event.modifiers === Qt.NoModifier) {
|
||||
if (event.key === Qt.Key_Backspace) {
|
||||
backspace();
|
||||
} else if (event.key === Qt.Key_Return) {
|
||||
enter();
|
||||
} else if (event.text != "") {
|
||||
keyPress(event.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// trigger turning letter into dot after 500 milliseconds
|
||||
Timer {
|
||||
id: letterTimer
|
||||
interval: 500
|
||||
running: false
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
lastKeyPressValue = 0;
|
||||
indexWithNumber = -2;
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
topMargin: units.gridUnit
|
||||
bottomMargin: units.gridUnit
|
||||
}
|
||||
spacing: units.gridUnit
|
||||
|
||||
// pin dot display
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.minimumHeight: units.gridUnit * 0.5
|
||||
Layout.maximumWidth: parent.width
|
||||
|
||||
Label {
|
||||
visible: root.password.length === 0
|
||||
anchors.centerIn: parent
|
||||
text: pinLabel
|
||||
font.pointSize: 12
|
||||
color: "#616161"
|
||||
}
|
||||
RowLayout {
|
||||
id: dotDisplay
|
||||
anchors.centerIn: parent
|
||||
height: units.gridUnit // maintain height when letter is shown
|
||||
spacing: 6
|
||||
|
||||
Repeater {
|
||||
model: root.password.length
|
||||
delegate: Rectangle { // dot
|
||||
visible: index !== indexWithNumber // hide dot if number is shown
|
||||
Layout.preferredWidth: units.gridUnit * 0.25
|
||||
Layout.preferredHeight: Layout.preferredWidth
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
radius: width
|
||||
color: "#424242"
|
||||
}
|
||||
}
|
||||
Label { // number/letter
|
||||
visible: root.password.length-1 === indexWithNumber // hide label if no label needed
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
color: "#424242"
|
||||
text: lastKeyPressValue
|
||||
font.pointSize: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// separator
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
height: 1
|
||||
color: "#eeeeee"
|
||||
}
|
||||
|
||||
// number keys
|
||||
GridLayout {
|
||||
property string thePw
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Layout.leftMargin: units.gridUnit * 0.5
|
||||
Layout.rightMargin: units.gridUnit * 0.5
|
||||
Layout.maximumWidth: units.gridUnit * 22
|
||||
Layout.maximumHeight: units.gridUnit * 12.5
|
||||
columns: 4
|
||||
|
||||
// numpad keys
|
||||
Repeater {
|
||||
model: ["1", "2", "3", "R", "4", "5", "6", "0", "7", "8", "9", "E"]
|
||||
|
||||
delegate: Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
Rectangle {
|
||||
id: keyRect
|
||||
anchors.centerIn: parent
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
radius: 5
|
||||
color: "white"
|
||||
visible: modelData.length > 0
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressed: parent.color = "#e0e0e0"
|
||||
onReleased: parent.color = "white"
|
||||
onClicked: {
|
||||
if (modelData === "R") {
|
||||
backspace();
|
||||
} else if (modelData === "E") {
|
||||
enter();
|
||||
} else {
|
||||
keyPress(modelData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
anchors.fill: keyRect
|
||||
source: keyRect
|
||||
cached: true
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 1
|
||||
radius: 4
|
||||
samples: 6
|
||||
color: "#e0e0e0"
|
||||
}
|
||||
|
||||
PlasmaComponents.Label {
|
||||
visible: modelData !== "R" && modelData !== "E"
|
||||
text: modelData
|
||||
anchors.centerIn: parent
|
||||
font.pointSize: 18
|
||||
color: "#424242"
|
||||
}
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
visible: modelData === "R"
|
||||
anchors.centerIn: parent
|
||||
// colorGroup: PlasmaCore.ColorScope.backgroundColor
|
||||
source: "edit-clear"
|
||||
}
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
visible: modelData === "E"
|
||||
anchors.centerIn: parent
|
||||
// colorGroup: PlasmaCore.ColorScope.backgroundColor
|
||||
source: "go-next"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,68 +22,183 @@ import QtGraphicalEffects 1.12
|
|||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.workspace.keyboardlayout 1.0
|
||||
import org.kde.notificationmanager 1.1 as Notifications
|
||||
import "../components"
|
||||
|
||||
PlasmaCore.ColorScope {
|
||||
id: root
|
||||
|
||||
property string password
|
||||
|
||||
property bool isWidescreen: root.height < root.width * 0.75
|
||||
property bool notificationsShown: phoneNotificationsList.count !== 0
|
||||
|
||||
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
|
||||
anchors.fill: parent
|
||||
|
||||
BrightnessContrast {
|
||||
id: darken
|
||||
function isPinDrawerOpen() {
|
||||
return passwordFlickable.contentY === passwordFlickable.columnHeight;
|
||||
}
|
||||
|
||||
// blur background once keypad is open
|
||||
FastBlur {
|
||||
id: blur
|
||||
cached: true
|
||||
anchors.fill: parent
|
||||
source: wallpaper
|
||||
brightness: -(passwordFlickable.contentY / passwordFlickable.columnHeight * 0.6)
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
id: clockShadow
|
||||
anchors.fill: clock
|
||||
source: clock
|
||||
horizontalOffset: 1
|
||||
verticalOffset: 1
|
||||
radius: 6
|
||||
samples: 14
|
||||
spread: 0.3
|
||||
color: PlasmaCore.ColorScope.backgroundColor
|
||||
visible: true
|
||||
|
||||
// hide when keypad is shown
|
||||
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
||||
property bool doBlur: notificationsShown || isPinDrawerOpen() // only blur once animation finished for performance
|
||||
|
||||
Behavior on doBlur {
|
||||
NumberAnimation {
|
||||
target: blur
|
||||
property: "radius"
|
||||
duration: 1000
|
||||
to: blur.doBlur ? 0 : 50
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
PropertyAction {
|
||||
target: blur
|
||||
property: "visible"
|
||||
value: blur.doBlur
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Clock {
|
||||
id: clock
|
||||
|
||||
property Item shadow: clockShadow
|
||||
|
||||
anchors.leftMargin: units.gridUnit
|
||||
anchors.rightMargin: units.gridUnit
|
||||
anchors.topMargin: units.gridUnit * 3
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
Notifications.WatchedNotificationsModel {
|
||||
id: notifModel
|
||||
}
|
||||
|
||||
// header bar
|
||||
SimpleHeaderBar {
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
height: units.gridUnit
|
||||
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
||||
}
|
||||
|
||||
MediaControls {
|
||||
// phone clock component
|
||||
ColumnLayout {
|
||||
id: phoneClockComponent
|
||||
visible: !isWidescreen
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
topMargin: root.height / 2 - (height / 2 + units.gridUnit * 2)
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
spacing: 0
|
||||
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
||||
|
||||
states: State {
|
||||
name: "notification"; when: notificationsShown
|
||||
PropertyChanges { target: phoneClockComponent; anchors.topMargin: units.gridUnit * 5 }
|
||||
}
|
||||
|
||||
transitions: Transition {
|
||||
NumberAnimation {
|
||||
properties: "anchors.topMargin"
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
Clock {
|
||||
id: phoneClock
|
||||
alignment: Qt.AlignHCenter
|
||||
Layout.bottomMargin: units.gridUnit * 2 // keep spacing even if media controls are gone
|
||||
}
|
||||
MediaControls {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: units.gridUnit * 25
|
||||
Layout.minimumWidth: units.gridUnit * 15
|
||||
Layout.leftMargin: units.gridUnit
|
||||
Layout.rightMargin: units.gridUnit
|
||||
z: 5
|
||||
}
|
||||
}
|
||||
|
||||
// tablet clock component
|
||||
Item {
|
||||
id: tabletClockComponent
|
||||
visible: isWidescreen
|
||||
width: parent.width / 2
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
leftMargin: units.gridUnit * 3
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: tabletLayout
|
||||
anchors.centerIn: parent
|
||||
spacing: units.gridUnit
|
||||
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
||||
|
||||
Clock {
|
||||
id: tabletClock
|
||||
alignment: Qt.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: units.gridUnit * 20
|
||||
}
|
||||
MediaControls {
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: units.gridUnit * 25
|
||||
Layout.minimumWidth: units.gridUnit * 20
|
||||
z: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// phone notifications list
|
||||
NotificationsList {
|
||||
id: phoneNotificationsList
|
||||
visible: !isWidescreen
|
||||
z: passwordFlickable.contentY === 0 ? 5 : 0 // prevent mousearea from interfering with pin drawer
|
||||
anchors {
|
||||
top: phoneClockComponent.bottom
|
||||
topMargin: units.gridUnit
|
||||
bottom: scrollUpIcon.top
|
||||
bottomMargin: units.gridUnit
|
||||
left: parent.left
|
||||
leftMargin: units.gridUnit
|
||||
right: parent.right
|
||||
rightMargin: units.gridUnit
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
||||
z: 5
|
||||
}
|
||||
|
||||
|
||||
// tablet notifications list
|
||||
ColumnLayout {
|
||||
visible: isWidescreen
|
||||
z: passwordFlickable.contentY === 0 ? 5 : 0 // prevent mousearea from interfering with pin drawer
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
left: tabletClockComponent.right
|
||||
right: parent.right
|
||||
rightMargin: units.gridUnit
|
||||
}
|
||||
|
||||
NotificationsList {
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: this.notificationListHeight
|
||||
Layout.minimumWidth: units.gridUnit * 15
|
||||
Layout.maximumWidth: units.gridUnit * 25
|
||||
}
|
||||
}
|
||||
|
||||
// scroll up icon
|
||||
PlasmaCore.IconItem {
|
||||
id: scrollUpIcon
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottomMargin: units.gridUnit + passwordFlickable.contentY * 0.5
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
||||
|
|
@ -116,8 +231,10 @@ PlasmaCore.ColorScope {
|
|||
|
||||
// wipe password if it is more than half way down the screen
|
||||
onContentYChanged: {
|
||||
if (contentY < columnHeight / 2)
|
||||
if (contentY < columnHeight / 2) {
|
||||
root.password = "";
|
||||
keypad.pinLabel = qsTr("Enter PIN");
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
|
@ -125,99 +242,22 @@ PlasmaCore.ColorScope {
|
|||
anchors.bottom: parent.bottom
|
||||
|
||||
width: parent.width
|
||||
spacing: units.gridUnit * 2
|
||||
spacing: units.gridUnit
|
||||
opacity: Math.sin((Math.PI / 2) * (passwordFlickable.contentY / passwordFlickable.columnHeight) + 1.5 * Math.PI) + 1
|
||||
|
||||
PlasmaComponents.Label {
|
||||
// scroll down icon
|
||||
PlasmaCore.IconItem {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("Enter PIN")
|
||||
font.pointSize: 12
|
||||
}
|
||||
|
||||
Row {
|
||||
id: dotDisplay
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 6
|
||||
|
||||
Layout.minimumHeight: units.gridUnit
|
||||
Layout.maximumWidth: parent.width
|
||||
|
||||
Repeater {
|
||||
model: root.password.length
|
||||
delegate: Rectangle {
|
||||
width: units.gridUnit
|
||||
height: width
|
||||
radius: width
|
||||
color: Qt.rgba(255, 255, 255, 0.3)
|
||||
}
|
||||
}
|
||||
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
|
||||
source: "arrow-down"
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
id: numBlock
|
||||
property string thePw
|
||||
|
||||
Keypad {
|
||||
id: keypad
|
||||
focus: passwordFlickable.contentY === passwordFlickable.columnHeight
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: units.gridUnit * 16
|
||||
Layout.minimumHeight: units.gridUnit * 17
|
||||
Layout.maximumWidth: root.width
|
||||
Layout.bottomMargin: units.gridUnit * 2
|
||||
Layout.leftMargin: units.gridUnit * 2
|
||||
Layout.rightMargin: units.gridUnit * 2
|
||||
rowSpacing: units.gridUnit
|
||||
|
||||
columns: 3
|
||||
|
||||
Repeater {
|
||||
model: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "R", "0", "E"]
|
||||
delegate: Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: units.gridUnit * 3
|
||||
height: width
|
||||
radius: 12
|
||||
color: Qt.rgba(PlasmaCore.ColorScope.backgroundColor.r, PlasmaCore.ColorScope.backgroundColor.g, PlasmaCore.ColorScope.backgroundColor.b, ma.pressed ? 0.8 : 0.3)
|
||||
visible: modelData.length > 0
|
||||
|
||||
MouseArea {
|
||||
id: ma
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
if (modelData === "R") {
|
||||
root.password = root.password.substr(0, root.password.length - 1);
|
||||
} else if (modelData === "E") {
|
||||
authenticator.tryUnlock(root.password);
|
||||
} else {
|
||||
root.password += modelData
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaComponents.Label {
|
||||
visible: modelData !== "R" && modelData !== "E"
|
||||
text: modelData
|
||||
anchors.centerIn: parent
|
||||
font.pointSize: 16
|
||||
}
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
visible: modelData === "R"
|
||||
anchors.centerIn: parent
|
||||
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
|
||||
source: "edit-clear"
|
||||
}
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
visible: modelData === "E"
|
||||
anchors.centerIn: parent
|
||||
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
|
||||
source: "go-next"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
58
look-and-feel/contents/lockscreen/NotificationsList.qml
Normal file
58
look-and-feel/contents/lockscreen/NotificationsList.qml
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Copyright (C) 2020 Devin Lin <espidev@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtGraphicalEffects 1.12
|
||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.notificationmanager 1.1 as Notifications
|
||||
import "../components"
|
||||
|
||||
Item {
|
||||
property alias notificationListHeight: notificationListView.contentHeight
|
||||
property int count: notificationListView.count
|
||||
|
||||
ListView {
|
||||
id: notificationListView
|
||||
model: notifModel
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
height: Math.min(contentHeight, parent.height) // don't take up the entire screen for notification list view
|
||||
|
||||
interactive: contentHeight > parent.height // only allow scrolling on notifications list if it is long enough
|
||||
clip: true
|
||||
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
||||
spacing: units.gridUnit
|
||||
|
||||
delegate: Column {
|
||||
width: notificationListView.width
|
||||
spacing: units.smallSpacing
|
||||
|
||||
// insert application heading here once application grouping is implemented
|
||||
|
||||
SimpleNotification {
|
||||
notification: model
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
108
look-and-feel/contents/lockscreen/SimpleHeaderBar.qml
Normal file
108
look-and-feel/contents/lockscreen/SimpleHeaderBar.qml
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright 2019 Marco Martin <mart@kde.org>
|
||||
* 2020 Devin Lin <espidev@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
|
||||
*/
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||
import org.kde.plasma.workspace.components 2.0 as PW
|
||||
|
||||
import "indicators" as Indicators
|
||||
|
||||
// a simple version of the task panel
|
||||
// in the future, it should share components with the existing task panel
|
||||
PlasmaCore.ColorScope {
|
||||
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
anchors.fill: icons
|
||||
visible: !showingApp
|
||||
cached: true
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 1
|
||||
radius: 4.0
|
||||
samples: 17
|
||||
color: Qt.rgba(0,0,0,0.8)
|
||||
source: icons
|
||||
}
|
||||
|
||||
PlasmaCore.DataSource {
|
||||
id: timeSource
|
||||
engine: "time"
|
||||
connectedSources: ["Local"]
|
||||
interval: 60 * 1000
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: "transparent"
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: Qt.rgba(0, 0, 0, 0.1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: strengthLoader
|
||||
height: parent.height
|
||||
width: item ? item.width : 0
|
||||
source: Qt.resolvedUrl("indicators/SignalStrength.qml")
|
||||
}
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: clock
|
||||
anchors.fill: parent
|
||||
text: Qt.formatTime(timeSource.data.Local.DateTime, "hh:mm")
|
||||
color: PlasmaCore.ColorScope.textColor
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
font.pixelSize: height / 2
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: appletIconsRow
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
right: simpleIndicatorsLayout.left
|
||||
}
|
||||
height: parent.height
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: simpleIndicatorsLayout
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
rightMargin: units.smallSpacing
|
||||
}
|
||||
Indicators.Bluetooth {}
|
||||
Indicators.Wifi {}
|
||||
Indicators.Volume {}
|
||||
Indicators.Battery {}
|
||||
}
|
||||
}
|
||||
169
look-and-feel/contents/lockscreen/SimpleNotification.qml
Normal file
169
look-and-feel/contents/lockscreen/SimpleNotification.qml
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
Copyright (C) 2020 Devin Lin <espidev@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||
import org.kde.notificationmanager 1.1 as Notifications
|
||||
|
||||
import org.kde.kquickcontrolsaddons 2.0 as KQCAddons
|
||||
|
||||
import "../components"
|
||||
|
||||
// meant to be temporary, until the notifications components in plasma-workspace are available to used
|
||||
// https://invent.kde.org/plasma/plasma-workspace/-/blob/master/applets/notifications/package/contents/ui/NotificationItem.qml
|
||||
Item {
|
||||
property var notification
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: notifLayout.height + units.gridUnit
|
||||
|
||||
opacity: 1 - Math.min(1, 1.5 * Math.abs(rect.x) / width) // opacity during dismiss swipe
|
||||
|
||||
// notification
|
||||
Rectangle {
|
||||
id: rect
|
||||
|
||||
radius: 5
|
||||
color: "white"
|
||||
|
||||
height: parent.height
|
||||
width: parent.width
|
||||
|
||||
border.color: "#bdbdbd"
|
||||
border.width: 1
|
||||
|
||||
RowLayout {
|
||||
id: notifLayout
|
||||
height: textLayout.height
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: units.gridUnit * 0.5
|
||||
right: parent.right
|
||||
rightMargin: units.gridUnit * 0.5
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
spacing: units.smallSpacing / 2
|
||||
|
||||
// notif body
|
||||
ColumnLayout {
|
||||
id: textLayout
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
spacing: units.gridUnit / 2
|
||||
|
||||
Label {
|
||||
text: notification.summary
|
||||
color: "#212121"
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: implicitHeight
|
||||
maximumLineCount: 3
|
||||
wrapMode: Text.WordWrap
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: 11
|
||||
}
|
||||
Label {
|
||||
text: notification.body
|
||||
color: "#616161"
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: 10
|
||||
}
|
||||
}
|
||||
|
||||
// notification icon
|
||||
Item {
|
||||
id: iconContainer
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
Layout.preferredWidth: units.iconSizes.large
|
||||
Layout.preferredHeight: units.iconSizes.large
|
||||
Layout.topMargin: units.smallSpacing
|
||||
Layout.bottomMargin: units.smallSpacing
|
||||
|
||||
visible: iconItem.active || imageItem.active
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
id: iconItem
|
||||
// don't show two identical icons
|
||||
readonly property bool active: valid && source != notification.applicationIconSource
|
||||
anchors.fill: parent
|
||||
usesPlasmaTheme: false
|
||||
smooth: true
|
||||
source: {
|
||||
let icon = notification.icon;
|
||||
if (typeof icon !== "string") return "";
|
||||
if (icon === "dialog-information") return "";
|
||||
return icon;
|
||||
}
|
||||
visible: active
|
||||
}
|
||||
|
||||
KQCAddons.QImageItem {
|
||||
id: imageItem
|
||||
readonly property bool active: !null && nativeWidth > 0
|
||||
anchors.fill: parent
|
||||
smooth: true
|
||||
fillMode: KQCAddons.QImageItem.PreserveAspectFit
|
||||
visible: active
|
||||
image: typeof notification.icon === "object" ? notification.icon : undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// swipe gesture for dismissing notification (left/right)
|
||||
MouseArea {
|
||||
id: dismissSwipe
|
||||
anchors.fill: parent
|
||||
drag.axis: Drag.XAxis
|
||||
drag.target: rect
|
||||
|
||||
onReleased: {
|
||||
if (Math.abs(rect.x) > width / 2) { // dismiss notification when finished swipe
|
||||
notifModel.close(notification.id);
|
||||
} else {
|
||||
slideAnim.restart();
|
||||
}
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
id: slideAnim
|
||||
target: rect
|
||||
property: "x"
|
||||
to: 0
|
||||
duration: units.longDuration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
anchors.fill: rect
|
||||
source: rect
|
||||
horizontalOffset: 1
|
||||
verticalOffset: 1
|
||||
radius: 4
|
||||
samples: 6
|
||||
color: "#616161"
|
||||
}
|
||||
}
|
||||
56
look-and-feel/contents/lockscreen/indicators/Battery.qml
Normal file
56
look-and-feel/contents/lockscreen/indicators/Battery.qml
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 2019 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
|
||||
*/
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Layouts 1.4
|
||||
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||
import org.kde.plasma.workspace.components 2.0 as PW
|
||||
|
||||
|
||||
RowLayout {
|
||||
visible: pmSource.data["Battery"]["Has Cumulative"]
|
||||
|
||||
PW.BatteryIcon {
|
||||
id: battery
|
||||
Layout.preferredWidth: height
|
||||
Layout.fillHeight: true
|
||||
hasBattery: true
|
||||
percent: pmSource.data["Battery"]["Percent"]
|
||||
pluggedIn: pmSource.data["AC Adapter"] ? pmSource.data["AC Adapter"]["Plugged in"] : false
|
||||
|
||||
height: batteryLabel.height
|
||||
width: batteryLabel.height
|
||||
|
||||
PlasmaCore.DataSource {
|
||||
id: pmSource
|
||||
engine: "powermanagement"
|
||||
connectedSources: ["Battery", "AC Adapter"]
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: batteryLabel
|
||||
text: i18n("%1%", battery.percent)
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
color: PlasmaCore.ColorScope.textColor
|
||||
font.pixelSize: parent.height / 2
|
||||
}
|
||||
}
|
||||
62
look-and-feel/contents/lockscreen/indicators/Bluetooth.qml
Normal file
62
look-and-feel/contents/lockscreen/indicators/Bluetooth.qml
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
Copyright 2019 MArco MArtni <mart@kde.org>
|
||||
Copyright 2013-2017 Jan Grulich <jgrulich@redhat.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) version 3, or any
|
||||
later version accepted by the membership of KDE e.V. (or its
|
||||
successor approved by the membership of KDE e.V.), which shall
|
||||
act as a proxy defined in Section 6 of version 3 of the license.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Layouts 1.4
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||
import org.kde.bluezqt 1.0 as BluezQt
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
id: connectionIcon
|
||||
|
||||
property bool deviceConnected : false
|
||||
|
||||
source: deviceConnected ? "preferences-system-bluetooth-activated" : "preferences-system-bluetooth";
|
||||
colorGroup: PlasmaCore.ColorScope.colorGroup
|
||||
|
||||
visible: BluezQt.Manager.bluetoothOperational
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: height
|
||||
function updateStatus()
|
||||
{
|
||||
var connectedDevices = [];
|
||||
|
||||
for (var i = 0; i < BluezQt.Manager.devices.length; ++i) {
|
||||
var device = BluezQt.Manager.devices[i];
|
||||
if (device.connected) {
|
||||
connectedDevices.push(device);
|
||||
}
|
||||
}
|
||||
deviceConnected = connectedDevices.length > 0;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
BluezQt.Manager.deviceAdded.connect(updateStatus);
|
||||
BluezQt.Manager.deviceRemoved.connect(updateStatus);
|
||||
BluezQt.Manager.deviceChanged.connect(updateStatus);
|
||||
BluezQt.Manager.bluetoothBlockedChanged.connect(updateStatus);
|
||||
BluezQt.Manager.bluetoothOperationalChanged.connect(updateStatus);
|
||||
|
||||
updateStatus();
|
||||
}
|
||||
}
|
||||
44
look-and-feel/contents/lockscreen/indicators/Indicator.qml
Normal file
44
look-and-feel/contents/lockscreen/indicators/Indicator.qml
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2019 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
|
||||
*/
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Layouts 1.4
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||
|
||||
|
||||
RowLayout {
|
||||
|
||||
property alias icon: icon.source
|
||||
property alias text: label.text
|
||||
PlasmaCore.IconItem {
|
||||
id: icon
|
||||
colorGroup: PlasmaCore.ColorScope.colorGroup
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: height
|
||||
}
|
||||
PlasmaComponents.Label {
|
||||
id: label
|
||||
visible: text.length > 0
|
||||
color: PlasmaCore.ColorScope.textColor
|
||||
font.pixelSize: parent.height / 2
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright 2015 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
|
||||
*/
|
||||
|
||||
import QtQuick 2.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
import MeeGo.QOfono 0.2
|
||||
|
||||
import org.kde.plasma.plasmoid 2.0
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||
|
||||
|
||||
Item {
|
||||
|
||||
width: strengthIcon.height + strengthLabel.width
|
||||
Layout.minimumWidth: strengthIcon.height + strengthLabel.width
|
||||
OfonoManager {
|
||||
id: ofonoManager
|
||||
onAvailableChanged: {
|
||||
console.log("Ofono is " + available)
|
||||
}
|
||||
onModemAdded: {
|
||||
console.log("modem added " + modem)
|
||||
}
|
||||
onModemRemoved: console.log("modem removed")
|
||||
}
|
||||
|
||||
OfonoNetworkRegistration {
|
||||
id: netreg
|
||||
Component.onCompleted: {
|
||||
netreg.scan()
|
||||
updateStrengthIcon()
|
||||
}
|
||||
|
||||
onNetworkOperatorsChanged : {
|
||||
console.log("operators :"+netreg.currentOperator["Name"].toString())
|
||||
}
|
||||
modemPath: ofonoManager.modems.length ? ofonoManager.modems[0] : ""
|
||||
function updateStrengthIcon() {
|
||||
if (netreg.strength >= 100) {
|
||||
strengthIcon.source = "network-mobile-100";
|
||||
} else if (netreg.strength >= 80) {
|
||||
strengthIcon.source = "network-mobile-80";
|
||||
} else if (netreg.strength >= 60) {
|
||||
strengthIcon.source = "network-mobile-60";
|
||||
} else if (netreg.strength >= 40) {
|
||||
strengthIcon.source = "network-mobile-40";
|
||||
} else if (netreg.strength >= 20) {
|
||||
strengthIcon.source = "network-mobile-20";
|
||||
} else {
|
||||
strengthIcon.source = "network-mobile-0";
|
||||
}
|
||||
}
|
||||
|
||||
onStrengthChanged: {
|
||||
console.log("Strength changed to " + netreg.strength)
|
||||
updateStrengthIcon()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
id: strengthIcon
|
||||
colorGroup: PlasmaCore.ColorScope.colorGroup
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: height
|
||||
height: parent.height
|
||||
}
|
||||
PlasmaComponents.Label {
|
||||
id: strengthLabel
|
||||
anchors {
|
||||
left: strengthIcon.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
text: netreg.strength + "% " + netreg.name
|
||||
color: PlasmaCore.ColorScope.textColor
|
||||
font.pixelSize: parent.height / 2
|
||||
}
|
||||
}
|
||||
176
look-and-feel/contents/lockscreen/indicators/Volume.qml
Normal file
176
look-and-feel/contents/lockscreen/indicators/Volume.qml
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
Copyright 2019 Aditya Mehra <Aix.m@outlook.com>
|
||||
Copyright 2014-2015 Harald Sitter <sitter@kde.org>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) version 3, or any
|
||||
later version accepted by the membership of KDE e.V. (or its
|
||||
successor approved by the membership of KDE e.V.), which shall
|
||||
act as a proxy defined in Section 6 of version 3 of the license.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Layouts 1.4
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||
import org.kde.plasma.private.volume 0.1
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
|
||||
id: paIcon
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: height
|
||||
property bool volumeFeedback: true
|
||||
property int maxVolumeValue: Math.round(100 * PulseAudio.NormalVolume / 100.0)
|
||||
property int volumeStep: Math.round(5 * PulseAudio.NormalVolume / 100.0)
|
||||
readonly property string dummyOutputName: "auto_null"
|
||||
source: paSinkModel.preferredSink && !isDummyOutput(paSinkModel.preferredSink)
|
||||
? iconName(paSinkModel.preferredSink.volume, paSinkModel.preferredSink.muted)
|
||||
: iconName(0, true)
|
||||
|
||||
colorGroup: PlasmaCore.ColorScope.colorGroup
|
||||
|
||||
visible: paSinkModel.preferredSink && paSinkModel.preferredSink.muted
|
||||
|
||||
function iconName(volume, muted, prefix) {
|
||||
if (!prefix) {
|
||||
prefix = "audio-volume";
|
||||
}
|
||||
var icon = null;
|
||||
var percent = volume / maxVolumeValue;
|
||||
if (percent <= 0.0 || muted) {
|
||||
icon = prefix + "-muted";
|
||||
} else if (percent <= 0.25) {
|
||||
icon = prefix + "-low";
|
||||
} else if (percent <= 0.75) {
|
||||
icon = prefix + "-medium";
|
||||
} else {
|
||||
icon = prefix + "-high";
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
function isDummyOutput(output) {
|
||||
return output && output.name === dummyOutputName;
|
||||
}
|
||||
|
||||
function boundVolume(volume) {
|
||||
return Math.max(PulseAudio.MinimalVolume, Math.min(volume, maxVolumeValue));
|
||||
}
|
||||
|
||||
function volumePercent(volume, max){
|
||||
if(!max) {
|
||||
max = PulseAudio.NormalVolume;
|
||||
}
|
||||
return Math.round(volume / max * 100.0);
|
||||
}
|
||||
|
||||
function playFeedback(sinkIndex) {
|
||||
if(!volumeFeedback){
|
||||
return;
|
||||
}
|
||||
if(sinkIndex == undefined) {
|
||||
sinkIndex = paSinkModel.preferredSink.index;
|
||||
}
|
||||
feedback.play(sinkIndex)
|
||||
}
|
||||
|
||||
function increaseVolume() {
|
||||
if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var volume = boundVolume(paSinkModel.preferredSink.volume + volumeStep);
|
||||
var percent = volumePercent(volume, maxVolumeValue);
|
||||
paSinkModel.preferredSink.muted = percent == 0;
|
||||
paSinkModel.preferredSink.volume = volume;
|
||||
osd.show(percent);
|
||||
playFeedback();
|
||||
|
||||
}
|
||||
|
||||
function decreaseVolume() {
|
||||
if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var volume = boundVolume(paSinkModel.preferredSink.volume - volumeStep);
|
||||
var percent = volumePercent(volume, maxVolumeValue);
|
||||
paSinkModel.preferredSink.muted = percent == 0;
|
||||
paSinkModel.preferredSink.volume = volume;
|
||||
osd.show(percent);
|
||||
playFeedback();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function muteVolume() {
|
||||
if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var toMute = !paSinkModel.preferredSink.muted;
|
||||
paSinkModel.preferredSink.muted = toMute;
|
||||
osd.show(toMute ? 0 : volumePercent(paSinkModel.preferredSink.volume, maxVolumeValue));
|
||||
if (!toMute) {
|
||||
playFeedback();
|
||||
}
|
||||
}
|
||||
|
||||
SinkModel {
|
||||
id: paSinkModel
|
||||
}
|
||||
|
||||
VolumeOSD {
|
||||
id: osd
|
||||
}
|
||||
|
||||
VolumeFeedback {
|
||||
id: feedback
|
||||
}
|
||||
|
||||
GlobalActionCollection {
|
||||
// KGlobalAccel cannot transition from kmix to something else, so if
|
||||
// the user had a custom shortcut set for kmix those would get lost.
|
||||
// To avoid this we hijack kmix name and actions. Entirely mental but
|
||||
// best we can do to not cause annoyance for the user.
|
||||
// The display name actually is updated to whatever registered last
|
||||
// though, so as far as user visible strings go we should be fine.
|
||||
// As of 2015-07-21:
|
||||
// componentName: kmix
|
||||
// actions: increase_volume, decrease_volume, mute
|
||||
name: "kmix"
|
||||
displayName: main.displayName
|
||||
|
||||
GlobalAction {
|
||||
objectName: "increase_volume"
|
||||
text: i18n("Increase Volume")
|
||||
shortcut: Qt.Key_VolumeUp
|
||||
onTriggered: increaseVolume()
|
||||
}
|
||||
|
||||
GlobalAction {
|
||||
objectName: "decrease_volume"
|
||||
text: i18n("Decrease Volume")
|
||||
shortcut: Qt.Key_VolumeDown
|
||||
onTriggered: decreaseVolume()
|
||||
}
|
||||
|
||||
GlobalAction {
|
||||
objectName: "mute"
|
||||
text: i18n("Mute")
|
||||
shortcut: Qt.Key_VolumeMute
|
||||
onTriggered: muteVolume()
|
||||
}
|
||||
}
|
||||
}
|
||||
60
look-and-feel/contents/lockscreen/indicators/Wifi.qml
Normal file
60
look-and-feel/contents/lockscreen/indicators/Wifi.qml
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Copyright 2019 MArco MArtni <mart@kde.org>
|
||||
Copyright 2013-2017 Jan Grulich <jgrulich@redhat.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) version 3, or any
|
||||
later version accepted by the membership of KDE e.V. (or its
|
||||
successor approved by the membership of KDE e.V.), which shall
|
||||
act as a proxy defined in Section 6 of version 3 of the license.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Layouts 1.4
|
||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||
import org.kde.plasma.networkmanagement 0.2 as PlasmaNM
|
||||
|
||||
PlasmaCore.IconItem {
|
||||
id: connectionIcon
|
||||
|
||||
source: connectionIconProvider.connectionIcon
|
||||
colorGroup: PlasmaCore.ColorScope.colorGroup
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: height
|
||||
|
||||
PlasmaComponents.BusyIndicator {
|
||||
id: connectingIndicator
|
||||
|
||||
anchors.fill: parent
|
||||
running: connectionIconProvider.connecting
|
||||
visible: running
|
||||
}
|
||||
|
||||
PlasmaNM.NetworkStatus {
|
||||
id: networkStatus
|
||||
}
|
||||
|
||||
PlasmaNM.NetworkModel {
|
||||
id: connectionModel
|
||||
}
|
||||
|
||||
PlasmaNM.Handler {
|
||||
id: handler
|
||||
}
|
||||
|
||||
PlasmaNM.ConnectionIcon {
|
||||
id: connectionIconProvider
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue