mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-08-02 17:54:45 +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 2.8
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
import QtQuick.Controls 2.5
|
import QtQuick.Controls 2.5
|
||||||
|
import QtGraphicalEffects 1.12
|
||||||
import org.kde.plasma.core 2.0
|
import org.kde.plasma.core 2.0
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
readonly property bool softwareRendering: GraphicsInfo.api === GraphicsInfo.Software
|
readonly property bool softwareRendering: GraphicsInfo.api === GraphicsInfo.Software
|
||||||
|
|
||||||
|
property int alignment
|
||||||
|
Layout.alignment: alignment
|
||||||
|
spacing: units.gridUnit
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: Qt.formatTime(timeSource.data["Local"]["DateTime"])
|
text: Qt.formatTime(timeSource.data["Local"]["DateTime"], "h:mm ap")
|
||||||
color: ColorScope.textColor
|
color: ColorScope.textColor
|
||||||
style: softwareRendering ? Text.Outline : Text.Normal
|
style: softwareRendering ? Text.Outline : Text.Normal
|
||||||
styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" //no outline, doesn't matter
|
styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" // no outline, doesn't matter
|
||||||
font.pointSize: 40
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
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 {
|
Label {
|
||||||
text: Qt.formatDate(timeSource.data["Local"]["DateTime"], Qt.DefaultLocaleLongDate)
|
text: Qt.formatDate(timeSource.data["Local"]["DateTime"], "ddd, MMM d")
|
||||||
color: ColorScope.textColor
|
color: ColorScope.textColor
|
||||||
style: softwareRendering ? Text.Outline : Text.Normal
|
style: softwareRendering ? Text.Outline : Text.Normal
|
||||||
styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" //no outline, doesn't matter
|
styleColor: softwareRendering ? ColorScope.backgroundColor : "transparent" // no outline, doesn't matter
|
||||||
font.pointSize: 16
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: alignment
|
||||||
|
font.pointSize: 10
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: DropShadow {
|
||||||
|
verticalOffset: 1
|
||||||
|
radius: 4
|
||||||
|
samples: 6
|
||||||
|
color: "#757575"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DataSource {
|
DataSource {
|
||||||
id: timeSource
|
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,6 +22,7 @@ import QtGraphicalEffects 1.12
|
||||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
import org.kde.plasma.workspace.keyboardlayout 1.0
|
import org.kde.plasma.workspace.keyboardlayout 1.0
|
||||||
|
import org.kde.notificationmanager 1.1 as Notifications
|
||||||
import "../components"
|
import "../components"
|
||||||
|
|
||||||
PlasmaCore.ColorScope {
|
PlasmaCore.ColorScope {
|
||||||
|
|
@ -29,61 +30,175 @@ PlasmaCore.ColorScope {
|
||||||
|
|
||||||
property string password
|
property string password
|
||||||
|
|
||||||
|
property bool isWidescreen: root.height < root.width * 0.75
|
||||||
|
property bool notificationsShown: phoneNotificationsList.count !== 0
|
||||||
|
|
||||||
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
|
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
BrightnessContrast {
|
function isPinDrawerOpen() {
|
||||||
id: darken
|
return passwordFlickable.contentY === passwordFlickable.columnHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// blur background once keypad is open
|
||||||
|
FastBlur {
|
||||||
|
id: blur
|
||||||
|
cached: true
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: wallpaper
|
source: wallpaper
|
||||||
brightness: -(passwordFlickable.contentY / passwordFlickable.columnHeight * 0.6)
|
visible: true
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DropShadow {
|
Notifications.WatchedNotificationsModel {
|
||||||
id: clockShadow
|
id: notifModel
|
||||||
anchors.fill: clock
|
|
||||||
source: clock
|
|
||||||
horizontalOffset: 1
|
|
||||||
verticalOffset: 1
|
|
||||||
radius: 6
|
|
||||||
samples: 14
|
|
||||||
spread: 0.3
|
|
||||||
color: PlasmaCore.ColorScope.backgroundColor
|
|
||||||
|
|
||||||
// hide when keypad is shown
|
|
||||||
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Clock {
|
// header bar
|
||||||
id: clock
|
SimpleHeaderBar {
|
||||||
|
|
||||||
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
|
|
||||||
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
|
||||||
}
|
|
||||||
|
|
||||||
MediaControls {
|
|
||||||
anchors {
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
height: units.gridUnit
|
||||||
|
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
left: parent.left
|
||||||
leftMargin: units.gridUnit
|
leftMargin: units.gridUnit
|
||||||
right: parent.right
|
right: parent.right
|
||||||
rightMargin: units.gridUnit
|
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 {
|
PlasmaCore.IconItem {
|
||||||
|
id: scrollUpIcon
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottomMargin: units.gridUnit + passwordFlickable.contentY * 0.5
|
anchors.bottomMargin: units.gridUnit + passwordFlickable.contentY * 0.5
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
opacity: 1 - (passwordFlickable.contentY / passwordFlickable.columnHeight)
|
||||||
|
|
@ -116,8 +231,10 @@ PlasmaCore.ColorScope {
|
||||||
|
|
||||||
// wipe password if it is more than half way down the screen
|
// wipe password if it is more than half way down the screen
|
||||||
onContentYChanged: {
|
onContentYChanged: {
|
||||||
if (contentY < columnHeight / 2)
|
if (contentY < columnHeight / 2) {
|
||||||
root.password = "";
|
root.password = "";
|
||||||
|
keypad.pinLabel = qsTr("Enter PIN");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
|
@ -125,99 +242,22 @@ PlasmaCore.ColorScope {
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
width: parent.width
|
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
|
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
|
Layout.alignment: Qt.AlignHCenter
|
||||||
text: qsTr("Enter PIN")
|
colorGroup: PlasmaCore.Theme.ComplementaryColorGroup
|
||||||
font.pointSize: 12
|
source: "arrow-down"
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Keypad {
|
||||||
id: dotDisplay
|
id: keypad
|
||||||
Layout.alignment: Qt.AlignHCenter
|
focus: passwordFlickable.contentY === passwordFlickable.columnHeight
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
id: numBlock
|
|
||||||
property string thePw
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.minimumHeight: units.gridUnit * 16
|
Layout.minimumHeight: units.gridUnit * 17
|
||||||
Layout.maximumWidth: root.width
|
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