diff --git a/look-and-feel/contents/components/UserDelegate.qml b/look-and-feel/contents/components/UserDelegate.qml new file mode 100644 index 0000000..b043af9 --- /dev/null +++ b/look-and-feel/contents/components/UserDelegate.qml @@ -0,0 +1,191 @@ +/* + * Copyright 2014 David Edmundson + * Copyright 2014 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 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 Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.8 +import QtQuick.Layouts 1.3 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 2.0 as PlasmaComponents + +Item { + id: wrapper + + // If we're using software rendering, draw outlines instead of shadows + // See https://bugs.kde.org/show_bug.cgi?id=398317 + readonly property bool softwareRendering: GraphicsInfo.api === GraphicsInfo.Software + + property bool isCurrent: true + + readonly property var m: model + property string name + property string userName + property string avatarPath + property string iconSource + property bool constrainText: true + property alias nameFontSize: usernameDelegate.font.pointSize + property int fontSize: config.fontSize + signal clicked() + + property real faceSize: Math.min(width, height - usernameDelegate.height - units.smallSpacing) + + opacity: isCurrent ? 1.0 : 0.5 + + Behavior on opacity { + OpacityAnimator { + duration: units.longDuration + } + } + + // Draw a translucent background circle under the user picture + Rectangle { + anchors.centerIn: imageSource + width: imageSource.width - 2 // Subtract to prevent fringing + height: width + radius: width / 2 + + color: PlasmaCore.ColorScope.backgroundColor + opacity: 0.6 + } + + Item { + id: imageSource + anchors { + bottom: usernameDelegate.top + bottomMargin: units.largeSpacing + horizontalCenter: parent.horizontalCenter + } + Behavior on width { + PropertyAnimation { + from: faceSize + duration: units.longDuration * 2; + } + } + width: isCurrent ? faceSize : faceSize - units.largeSpacing + height: width + + //Image takes priority, taking a full path to a file, if that doesn't exist we show an icon + Image { + id: face + source: wrapper.avatarPath + sourceSize: Qt.size(faceSize, faceSize) + fillMode: Image.PreserveAspectCrop + anchors.fill: parent + } + + PlasmaCore.IconItem { + id: faceIcon + source: iconSource + visible: (face.status == Image.Error || face.status == Image.Null) + anchors.fill: parent + anchors.margins: units.gridUnit * 0.5 // because mockup says so... + colorGroup: PlasmaCore.ColorScope.colorGroup + } + } + + ShaderEffect { + anchors { + bottom: usernameDelegate.top + bottomMargin: units.largeSpacing + horizontalCenter: parent.horizontalCenter + } + + width: imageSource.width + height: imageSource.height + + supportsAtlasTextures: true + + property var source: ShaderEffectSource { + sourceItem: imageSource + // software rendering is just a fallback so we can accept not having a rounded avatar here + hideSource: wrapper.GraphicsInfo.api !== GraphicsInfo.Software + live: true // otherwise the user in focus will show a blurred avatar + } + + property var colorBorder: PlasmaCore.ColorScope.textColor + + //draw a circle with an antialised border + //innerRadius = size of the inner circle with contents + //outerRadius = size of the border + //blend = area to blend between two colours + //all sizes are normalised so 0.5 == half the width of the texture + + //if copying into another project don't forget to connect themeChanged to update() + //but in SDDM that's a bit pointless + fragmentShader: " + varying highp vec2 qt_TexCoord0; + uniform highp float qt_Opacity; + uniform lowp sampler2D source; + + uniform lowp vec4 colorBorder; + highp float blend = 0.01; + highp float innerRadius = 0.47; + highp float outerRadius = 0.49; + lowp vec4 colorEmpty = vec4(0.0, 0.0, 0.0, 0.0); + + void main() { + lowp vec4 colorSource = texture2D(source, qt_TexCoord0.st); + + highp vec2 m = qt_TexCoord0 - vec2(0.5, 0.5); + highp float dist = sqrt(m.x * m.x + m.y * m.y); + + if (dist < innerRadius) + gl_FragColor = colorSource; + else if (dist < innerRadius + blend) + gl_FragColor = mix(colorSource, colorBorder, ((dist - innerRadius) / blend)); + else if (dist < outerRadius) + gl_FragColor = colorBorder; + else if (dist < outerRadius + blend) + gl_FragColor = mix(colorBorder, colorEmpty, ((dist - outerRadius) / blend)); + else + gl_FragColor = colorEmpty ; + + gl_FragColor = gl_FragColor * qt_Opacity; + } + " + } + + PlasmaComponents.Label { + id: usernameDelegate + font.pointSize: Math.max(fontSize + 2,theme.defaultFont.pointSize + 2) + anchors { + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + } + height: implicitHeight // work around stupid bug in Plasma Components that sets the height + width: constrainText ? parent.width : implicitWidth + text: wrapper.name + style: softwareRendering ? Text.Outline : Text.Normal + styleColor: softwareRendering ? PlasmaCore.ColorScope.backgroundColor : "transparent" //no outline, doesn't matter + elide: Text.ElideRight + horizontalAlignment: Text.AlignHCenter + //make an indication that this has active focus, this only happens when reached with keyboard navigation + font.underline: wrapper.activeFocus + } + + MouseArea { + anchors.fill: parent + hoverEnabled: true + + onClicked: wrapper.clicked(); + } + + Accessible.name: name + Accessible.role: Accessible.Button + function accessiblePressAction() { wrapper.clicked() } +} diff --git a/look-and-feel/contents/logout/Logout.qml b/look-and-feel/contents/logout/Logout.qml new file mode 100644 index 0000000..4247c1a --- /dev/null +++ b/look-and-feel/contents/logout/Logout.qml @@ -0,0 +1,114 @@ +/*************************************************************************** + * Copyright (C) 2014 by Aleix Pol Gonzalez * + * Copyright (C) 2020 by Linus Jahn * + * * + * 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 02110-1301 USA . * + ***************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Layouts 1.12 +import QtQuick.Controls 2.12 as Controls + +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.kcoreaddons 1.0 as KCoreAddons + +import "../components" + +import org.kde.plasma.private.sessions 2.0 + +PlasmaCore.ColorScope { + id: root + + signal logoutRequested() + signal haltRequested() + signal suspendRequested(int spdMethod) + signal rebootRequested() + signal rebootRequested2(int opt) + signal cancelRequested() + signal lockScreenRequested() + + Controls.Action { + onTriggered: root.cancelRequested() + shortcut: "Escape" + } + + Rectangle { + anchors.fill: parent + color: PlasmaCore.ColorScope.backgroundColor + opacity: 0.5 + } + + MouseArea { + anchors.fill: parent + onClicked: root.cancelRequested() + } + + KCoreAddons.KUser { + id: kuser + } + + Rectangle { + anchors.fill: contents + color: PlasmaCore.ColorScope.backgroundColor + radius: units.smallSpacing + } + + ColumnLayout { + id: contents + anchors.centerIn: parent + spacing: units.largeSpacing + width: Math.min(units.gridUnit * 20, root.width * 0.8) + height: Math.min(units.gridUnit * 25, root.height * 0.7) + + UserDelegate { + Layout.fillWidth: true + width: units.gridUnit * 7 + height: width + nameFontSize: theme.defaultFont.pointSize + 4 + constrainText: false + avatarPath: kuser.faceIconUrl + iconSource: "user-identity" + isCurrent: true + name: kuser.fullName + } + + ColumnLayout { + Controls.Button { + Layout.fillWidth: true + display: Controls.Button.TextUnderIcon + icon.name: "system-shutdown" + text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Shut Down") + onClicked: root.haltRequested() + } + + Controls.Button { + Layout.fillWidth: true + display: Controls.Button.TextUnderIcon + icon.name: "system-reboot" + text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Restart") + onClicked: root.rebootRequested() + } + + Controls.Button { + Layout.fillWidth: true + display: Controls.Button.TextUnderIcon + icon.name: "system-lock-screen" + text: i18nd("plasma_lookandfeel_org.kde.lookandfeel", "Lock screen") + onClicked: root.lockScreenRequested() + } + } + } +}